blob: aa9739d594b74cfab84555672d73f6c8029cae77 [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
rch675757b2016-07-29 16:40:115#include "net/quic/chromium/quic_http_stream.h"
[email protected]f702d572012-12-04 15:56:206
sclittle1edeeb22015-09-02 20:46:107#include <stdint.h>
8
danakjad1777e2016-04-16 00:56:429#include <memory>
bnc086b39e12016-06-24 13:05:2610#include <utility>
[email protected]f702d572012-12-04 15:56:2011
danakjad1777e2016-04-16 00:56:4212#include "base/memory/ptr_util.h"
fdoray92e35a72016-06-10 15:54:5513#include "base/run_loop.h"
xunjieli188bd402016-03-12 00:17:2514#include "base/strings/string_number_conversions.h"
gabf767595f2016-05-11 18:50:3515#include "base/threading/thread_task_runner_handle.h"
xunjieli84adaab2016-09-20 01:12:2816#include "base/time/time.h"
mmenkecbc2b712014-10-09 20:29:0717#include "net/base/chunked_upload_data_stream.h"
18#include "net/base/elements_upload_data_stream.h"
xunjieli84adaab2016-09-20 01:12:2819#include "net/base/load_timing_info.h"
20#include "net/base/load_timing_info_test_util.h"
[email protected]f702d572012-12-04 15:56:2021#include "net/base/net_errors.h"
22#include "net/base/test_completion_callback.h"
[email protected]b2d26cfd2012-12-11 10:36:0623#include "net/base/upload_bytes_element_reader.h"
[email protected]f702d572012-12-04 15:56:2024#include "net/http/http_response_headers.h"
[email protected]5db452202014-08-19 05:22:1525#include "net/http/transport_security_state.h"
mikecirone8b85c432016-09-08 19:11:0026#include "net/log/net_log_event_type.h"
xunjieli5fafe142016-03-23 23:32:5427#include "net/log/test_net_log.h"
28#include "net/log/test_net_log_util.h"
rch675757b2016-07-29 16:40:1129#include "net/quic/chromium/crypto/proof_verifier_chromium.h"
30#include "net/quic/chromium/quic_chromium_alarm_factory.h"
31#include "net/quic/chromium/quic_chromium_connection_helper.h"
32#include "net/quic/chromium/quic_chromium_packet_reader.h"
33#include "net/quic/chromium/quic_chromium_packet_writer.h"
rchd4db7c152016-07-29 21:58:1234#include "net/quic/core/congestion_control/send_algorithm_interface.h"
35#include "net/quic/core/crypto/crypto_protocol.h"
36#include "net/quic/core/crypto/quic_decrypter.h"
37#include "net/quic/core/crypto/quic_encrypter.h"
38#include "net/quic/core/crypto/quic_server_info.h"
39#include "net/quic/core/quic_connection.h"
40#include "net/quic/core/quic_http_utils.h"
41#include "net/quic/core/quic_write_blocked_list.h"
42#include "net/quic/core/spdy_utils.h"
rch1fe2eeb2015-10-26 14:45:5743#include "net/quic/test_tools/crypto_test_utils.h"
[email protected]f702d572012-12-04 15:56:2044#include "net/quic/test_tools/mock_clock.h"
[email protected]e8ff26842013-03-22 21:02:0545#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
[email protected]9db443912013-02-25 05:27:0346#include "net/quic/test_tools/mock_random.h"
[email protected]b1f287d2012-12-22 17:25:3947#include "net/quic/test_tools/quic_connection_peer.h"
[email protected]1e960032013-12-20 19:00:2048#include "net/quic/test_tools/quic_test_packet_maker.h"
[email protected]f702d572012-12-04 15:56:2049#include "net/quic/test_tools/quic_test_utils.h"
50#include "net/quic/test_tools/test_task_runner.h"
tbansalca83c002016-04-28 20:56:2851#include "net/socket/socket_performance_watcher.h"
[email protected]f702d572012-12-04 15:56:2052#include "net/socket/socket_test_util.h"
[email protected]6cca996b2013-01-25 07:43:3653#include "net/spdy/spdy_frame_builder.h"
54#include "net/spdy/spdy_framer.h"
55#include "net/spdy/spdy_http_utils.h"
56#include "net/spdy/spdy_protocol.h"
rch03b7a202016-02-05 00:54:2057#include "net/test/cert_test_util.h"
robpercival214763f2016-07-01 23:27:0158#include "net/test/gtest_util.h"
rsleevia69c79a2016-06-22 03:28:4359#include "net/test/test_data_directory.h"
[email protected]f702d572012-12-04 15:56:2060#include "testing/gmock/include/gmock/gmock.h"
61#include "testing/gtest/include/gtest/gtest.h"
62
robpercival214763f2016-07-01 23:27:0163using net::test::IsError;
64using net::test::IsOk;
65
bnc614a92d32016-04-04 13:56:0766using std::string;
[email protected]f702d572012-12-04 15:56:2067using testing::_;
[email protected]06ff5152013-08-29 01:03:0568using testing::AnyNumber;
69using testing::Return;
[email protected]f702d572012-12-04 15:56:2070
71namespace net {
[email protected]f702d572012-12-04 15:56:2072namespace test {
[email protected]f702d572012-12-04 15:56:2073namespace {
74
[email protected]16ba7742014-08-22 00:57:2575const char kUploadData[] = "Really nifty data!";
rch9ae5b3b2016-02-11 00:36:2976const char kDefaultServerHostName[] = "www.example.org";
Avi Drissman13fc8932015-12-20 04:40:4677const uint16_t kDefaultServerPort = 80;
[email protected]f702d572012-12-04 15:56:2078
79class TestQuicConnection : public QuicConnection {
80 public:
[email protected]1e960032013-12-20 19:00:2081 TestQuicConnection(const QuicVersionVector& versions,
[email protected]3aa9ca72014-02-27 19:39:4382 QuicConnectionId connection_id,
[email protected]f702d572012-12-04 15:56:2083 IPEndPoint address,
rch12fef552016-01-15 16:26:3184 QuicChromiumConnectionHelper* helper,
rch16c74d1d2016-04-22 06:14:0785 QuicChromiumAlarmFactory* alarm_factory,
jdorfman90d185f32016-01-15 13:22:4786 QuicPacketWriter* writer)
[email protected]66cd2d62014-08-01 18:42:3987 : QuicConnection(connection_id,
88 address,
89 helper,
rch16c74d1d2016-04-22 06:14:0790 alarm_factory,
jdorfman90d185f32016-01-15 13:22:4791 writer,
rtenneti6f48aa92015-03-16 02:18:4892 true /* owns_writer */,
93 Perspective::IS_CLIENT,
rtenneti6f48aa92015-03-16 02:18:4894 versions) {}
[email protected]f702d572012-12-04 15:56:2095
[email protected]fee17f72013-02-03 07:47:4196 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
rchdaf5a852016-07-26 19:42:5097 QuicConnectionPeer::SetSendAlgorithm(this, kDefaultPathId, send_algorithm);
[email protected]f702d572012-12-04 15:56:2098 }
99};
100
[email protected]63534512012-12-23 18:49:00101// Subclass of QuicHttpStream that closes itself when the first piece of data
102// is received.
103class AutoClosingStream : public QuicHttpStream {
104 public:
ckrasic4f9d88d2015-07-22 22:23:16105 explicit AutoClosingStream(
106 const base::WeakPtr<QuicChromiumClientSession>& session)
107 : QuicHttpStream(session) {}
[email protected]63534512012-12-23 18:49:00108
sclittlec4dc1a32015-09-24 00:15:45109 void OnHeadersAvailable(const SpdyHeaderBlock& headers,
110 size_t frame_len) override {
[email protected]63534512012-12-23 18:49:00111 Close(false);
[email protected]63534512012-12-23 18:49:00112 }
rchb27683c2015-07-29 23:53:50113
114 void OnDataAvailable() override { Close(false); }
[email protected]63534512012-12-23 18:49:00115};
116
maksim.sisov84e20c92016-06-23 08:49:34117// UploadDataStream that always returns errors on data read.
118class ReadErrorUploadDataStream : public UploadDataStream {
119 public:
120 enum class FailureMode { SYNC, ASYNC };
121
122 explicit ReadErrorUploadDataStream(FailureMode mode)
123 : UploadDataStream(true, 0), async_(mode), weak_factory_(this) {}
124 ~ReadErrorUploadDataStream() override {}
125
126 private:
127 void CompleteRead() { UploadDataStream::OnReadCompleted(ERR_FAILED); }
128
129 // UploadDataStream implementation:
maksim.sisov819ba852016-08-17 08:22:52130 int InitInternal(const BoundNetLog& net_log) override { return OK; }
maksim.sisov84e20c92016-06-23 08:49:34131
132 int ReadInternal(IOBuffer* buf, int buf_len) override {
133 if (async_ == FailureMode::ASYNC) {
134 base::ThreadTaskRunnerHandle::Get()->PostTask(
135 FROM_HERE, base::Bind(&ReadErrorUploadDataStream::CompleteRead,
136 weak_factory_.GetWeakPtr()));
137 return ERR_IO_PENDING;
138 }
139 return ERR_FAILED;
140 }
141
142 void ResetInternal() override {}
143
144 const FailureMode async_;
145
146 base::WeakPtrFactory<ReadErrorUploadDataStream> weak_factory_;
147
148 DISALLOW_COPY_AND_ASSIGN(ReadErrorUploadDataStream);
149};
150
xunjieli8dff50b2016-07-22 14:19:06151// A Callback that deletes the QuicHttpStream.
152class DeleteStreamCallback : public TestCompletionCallbackBase {
153 public:
154 DeleteStreamCallback(std::unique_ptr<QuicHttpStream> stream)
155 : stream_(std::move(stream)),
156 callback_(base::Bind(&DeleteStreamCallback::DeleteStream,
157 base::Unretained(this))) {}
158
159 const CompletionCallback& callback() const { return callback_; }
160
161 private:
162 void DeleteStream(int result) {
163 stream_.reset();
164 SetResult(result);
165 }
166
167 std::unique_ptr<QuicHttpStream> stream_;
168 CompletionCallback callback_;
169};
170
[email protected]f702d572012-12-04 15:56:20171} // namespace
172
[email protected]24e5bc52013-09-18 15:36:58173class QuicHttpStreamPeer {
174 public:
rch12fef552016-01-15 16:26:31175 static QuicChromiumClientStream* GetQuicChromiumClientStream(
[email protected]24e5bc52013-09-18 15:36:58176 QuicHttpStream* stream) {
177 return stream->stream_;
178 }
zhongyica364fbb2015-12-12 03:39:12179
180 static bool WasHandshakeConfirmed(QuicHttpStream* stream) {
181 return stream->was_handshake_confirmed_;
182 }
183
184 static void SetHandshakeConfirmed(QuicHttpStream* stream, bool confirmed) {
185 stream->was_handshake_confirmed_ = confirmed;
186 }
[email protected]24e5bc52013-09-18 15:36:58187};
188
[email protected]1e960032013-12-20 19:00:20189class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
[email protected]f702d572012-12-04 15:56:20190 protected:
[email protected]1e960032013-12-20 19:00:20191 static const bool kFin = true;
192 static const bool kIncludeVersion = true;
193 static const bool kIncludeCongestionFeedback = true;
194
[email protected]f702d572012-12-04 15:56:20195 // Holds a packet to be written to the wire, and the IO mode that should
196 // be used by the mock socket when performing the write.
197 struct PacketToWrite {
jokulikf2bd55c52016-03-24 22:35:30198 PacketToWrite(IoMode mode, QuicReceivedPacket* packet)
rjshaded5ced072015-12-18 19:26:02199 : mode(mode), packet(packet) {}
rtenneti15656ae2016-01-23 03:05:03200 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
[email protected]f702d572012-12-04 15:56:20201 IoMode mode;
jokulikf2bd55c52016-03-24 22:35:30202 QuicReceivedPacket* packet;
rtenneti15656ae2016-01-23 03:05:03203 int rv;
[email protected]f702d572012-12-04 15:56:20204 };
205
206 QuicHttpStreamTest()
xunjieli5fafe142016-03-23 23:32:54207 : use_closing_stream_(false),
rch1fe2eeb2015-10-26 14:45:57208 crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
[email protected]f702d572012-12-04 15:56:20209 read_buffer_(new IOBufferWithSize(4096)),
ckrasic3865ee0f2016-02-29 22:04:56210 promise_id_(kServerDataStreamId1),
[email protected]66ae5962014-05-22 11:13:05211 stream_id_(kClientDataStreamId1),
ckrasic3865ee0f2016-02-29 22:04:56212 connection_id_(2),
alyssar2adf3ac2016-05-03 17:12:58213 client_maker_(GetParam(),
214 connection_id_,
215 &clock_,
216 kDefaultServerHostName,
217 Perspective::IS_CLIENT),
218 server_maker_(GetParam(),
219 connection_id_,
220 &clock_,
221 kDefaultServerHostName,
222 Perspective::IS_SERVER),
ckrasic3865ee0f2016-02-29 22:04:56223 random_generator_(0),
224 response_offset_(0) {
martijn21968ea2016-02-24 18:46:20225 IPAddress ip(192, 0, 2, 33);
[email protected]f702d572012-12-04 15:56:20226 peer_addr_ = IPEndPoint(ip, 443);
227 self_addr_ = IPEndPoint(ip, 8435);
rtenneti4b06ae72014-08-26 03:43:43228 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
[email protected]f702d572012-12-04 15:56:20229 }
230
231 ~QuicHttpStreamTest() {
rtenneti85dcfac22015-03-27 20:22:19232 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
[email protected]f702d572012-12-04 15:56:20233 for (size_t i = 0; i < writes_.size(); i++) {
234 delete writes_[i].packet;
235 }
236 }
237
238 // Adds a packet to the list of expected writes.
danakjad1777e2016-04-16 00:56:42239 void AddWrite(std::unique_ptr<QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20240 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
[email protected]f702d572012-12-04 15:56:20241 }
242
rtenneti15656ae2016-01-23 03:05:03243 void AddWrite(IoMode mode, int rv) {
244 writes_.push_back(PacketToWrite(mode, rv));
245 }
246
[email protected]f702d572012-12-04 15:56:20247 // Returns the packet to be written at position |pos|.
jokulikf2bd55c52016-03-24 22:35:30248 QuicReceivedPacket* GetWrite(size_t pos) { return writes_[pos].packet; }
[email protected]f702d572012-12-04 15:56:20249
250 bool AtEof() {
rch37de576c2015-05-17 20:28:17251 return socket_data_->AllReadDataConsumed() &&
252 socket_data_->AllWriteDataConsumed();
[email protected]f702d572012-12-04 15:56:20253 }
254
danakjad1777e2016-04-16 00:56:42255 void ProcessPacket(std::unique_ptr<QuicReceivedPacket> packet) {
[email protected]1e960032013-12-20 19:00:20256 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
[email protected]f702d572012-12-04 15:56:20257 }
258
259 // Configures the test fixture to use the list of expected writes.
260 void Initialize() {
261 mock_writes_.reset(new MockWrite[writes_.size()]);
262 for (size_t i = 0; i < writes_.size(); i++) {
rtenneti15656ae2016-01-23 03:05:03263 if (writes_[i].packet == nullptr) {
264 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
265 } else {
266 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
267 writes_[i].packet->length());
268 }
bnc614a92d32016-04-04 13:56:07269 }
[email protected]f702d572012-12-04 15:56:20270
rtennetibe635732014-10-02 22:51:42271 socket_data_.reset(new StaticSocketDataProvider(
272 nullptr, 0, mock_writes_.get(), writes_.size()));
[email protected]f702d572012-12-04 15:56:20273
danakjad1777e2016-04-16 00:56:42274 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36275 socket_data_.get(), net_log_.bound().net_log()));
[email protected]e13201d82012-12-12 05:00:32276 socket->Connect(peer_addr_);
[email protected]f702d572012-12-04 15:56:20277 runner_ = new TestTaskRunner(&clock_);
[email protected]fee17f72013-02-03 07:47:41278 send_algorithm_ = new MockSendAlgorithm();
rch7dd15702015-07-01 18:57:57279 EXPECT_CALL(*send_algorithm_, InRecovery()).WillRepeatedly(Return(false));
280 EXPECT_CALL(*send_algorithm_, InSlowStart()).WillRepeatedly(Return(false));
rjshaded5ced072015-12-18 19:26:02281 EXPECT_CALL(*send_algorithm_, OnPacketSent(_, _, _, _, _))
282 .WillRepeatedly(Return(true));
rtenneti44f4a2e2015-08-07 14:00:07283 EXPECT_CALL(*send_algorithm_, RetransmissionDelay())
284 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
285 EXPECT_CALL(*send_algorithm_, GetCongestionWindow())
286 .WillRepeatedly(Return(kMaxPacketSize));
jokulik0e0a00c32016-06-13 21:51:58287 EXPECT_CALL(*send_algorithm_, PacingRate(_))
rtenneti44f4a2e2015-08-07 14:00:07288 .WillRepeatedly(Return(QuicBandwidth::Zero()));
fnkf57804c2016-03-17 20:57:07289 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _))
rtenneti44f4a2e2015-08-07 14:00:07290 .WillRepeatedly(Return(QuicTime::Delta::Zero()));
291 EXPECT_CALL(*send_algorithm_, BandwidthEstimate())
292 .WillRepeatedly(Return(QuicBandwidth::Zero()));
rch1e543ec2015-03-29 07:04:40293 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber());
rch16c74d1d2016-04-22 06:14:07294 helper_.reset(
295 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
296 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
297
298 connection_ =
299 new TestQuicConnection(SupportedVersions(GetParam()), connection_id_,
300 peer_addr_, helper_.get(), alarm_factory_.get(),
301 new QuicChromiumPacketWriter(socket.get()));
[email protected]f702d572012-12-04 15:56:20302 connection_->set_visitor(&visitor_);
[email protected]fee17f72013-02-03 07:47:41303 connection_->SetSendAlgorithm(send_algorithm_);
rch03b7a202016-02-05 00:54:20304
305 // Load a certificate that is valid for *.example.org
306 scoped_refptr<X509Certificate> test_cert(
307 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
308 EXPECT_TRUE(test_cert.get());
309
310 verify_details_.cert_verify_result.verified_cert = test_cert;
311 verify_details_.cert_verify_result.is_issued_by_known_root = true;
312 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details_);
313
xunjieli84adaab2016-09-20 01:12:28314 base::TimeTicks dns_end = base::TimeTicks::Now();
315 base::TimeTicks dns_start = dns_end - base::TimeDelta::FromMilliseconds(1);
ckrasic4f9d88d2015-07-22 22:23:16316 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36317 connection_, std::move(socket),
rtenneti1cd3b162015-09-29 02:58:28318 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
bnc614a92d32016-04-04 13:56:07319 &transport_security_state_,
danakjad1777e2016-04-16 00:56:42320 base::WrapUnique(static_cast<QuicServerInfo*>(nullptr)),
bncb07c05532015-05-14 19:07:20321 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
rch1fe2eeb2015-10-26 14:45:57322 PRIVACY_MODE_DISABLED),
rtenneti1cd3b162015-09-29 02:58:28323 kQuicYieldAfterPacketsRead,
324 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
rtennetia75df622015-06-21 23:59:50325 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
xunjieli84adaab2016-09-20 01:12:28326 "CONNECTION_UNKNOWN", dns_start, dns_end, &push_promise_index_,
327 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54328 /*socket_performance_watcher=*/nullptr, net_log_.bound().net_log()));
rtennetid39bd762015-06-12 01:05:52329 session_->Initialize();
xunjieli100937eb52016-09-15 20:09:37330 TestCompletionCallback callback;
331 session_->CryptoConnect(/*require_confirmation=*/false,
332 callback.callback());
[email protected]8ba81212013-05-03 13:11:48333 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
rjshaded5ced072015-12-18 19:26:02334 stream_.reset(use_closing_stream_
335 ? new AutoClosingStream(session_->GetWeakPtr())
336 : new QuicHttpStream(session_->GetWeakPtr()));
ckrasic3865ee0f2016-02-29 22:04:56337
338 promised_stream_.reset(use_closing_stream_
339 ? new AutoClosingStream(session_->GetWeakPtr())
340 : new QuicHttpStream(session_->GetWeakPtr()));
341
342 push_promise_[":path"] = "/bar";
343 push_promise_[":authority"] = "www.example.org";
344 push_promise_[":version"] = "HTTP/1.1";
345 push_promise_[":method"] = "GET";
346 push_promise_[":scheme"] = "https";
347
348 promised_response_[":status"] = "200 OK";
349 promised_response_[":version"] = "HTTP/1.1";
350 promised_response_["content-type"] = "text/plain";
351
352 promise_url_ = SpdyUtils::GetUrlFromHeaderBlock(push_promise_);
353
354 serialized_push_promise_ =
355 SpdyUtils::SerializeUncompressedHeaders(push_promise_);
[email protected]6cca996b2013-01-25 07:43:36356 }
357
bnc614a92d32016-04-04 13:56:07358 void SetRequest(const string& method,
359 const string& path,
[email protected]1e960032013-12-20 19:00:20360 RequestPriority priority) {
alyssar2adf3ac2016-05-03 17:12:58361 request_headers_ = client_maker_.GetRequestHeaders(method, "http", path);
[email protected]6cca996b2013-01-25 07:43:36362 }
363
bnc614a92d32016-04-04 13:56:07364 void SetResponse(const string& status, const string& body) {
alyssar2adf3ac2016-05-03 17:12:58365 response_headers_ = server_maker_.GetResponseHeaders(status);
[email protected]92bf17c2014-03-03 21:14:03366 response_data_ = body;
[email protected]6cca996b2013-01-25 07:43:36367 }
[email protected]f702d572012-12-04 15:56:20368
danakjad1777e2016-04-16 00:56:42369 std::unique_ptr<QuicReceivedPacket> InnerConstructDataPacket(
ckrasic3865ee0f2016-02-29 22:04:56370 QuicPacketNumber packet_number,
371 QuicStreamId stream_id,
372 bool should_include_version,
373 bool fin,
374 QuicStreamOffset offset,
alyssar2adf3ac2016-05-03 17:12:58375 base::StringPiece data,
376 QuicTestPacketMaker* maker) {
377 return maker->MakeDataPacket(packet_number, stream_id,
ckrasic3865ee0f2016-02-29 22:04:56378 should_include_version, fin, offset, data);
379 }
380
alyssar2adf3ac2016-05-03 17:12:58381 std::unique_ptr<QuicReceivedPacket> ConstructClientDataPacket(
rtennetia004d332015-08-28 06:44:57382 QuicPacketNumber packet_number,
[email protected]e8ff26842013-03-22 21:02:05383 bool should_include_version,
[email protected]f702d572012-12-04 15:56:20384 bool fin,
385 QuicStreamOffset offset,
386 base::StringPiece data) {
ckrasic3865ee0f2016-02-29 22:04:56387 return InnerConstructDataPacket(packet_number, stream_id_,
alyssar2adf3ac2016-05-03 17:12:58388 should_include_version, fin, offset, data,
389 &client_maker_);
390 }
391
392 std::unique_ptr<QuicReceivedPacket> ConstructServerDataPacket(
393 QuicPacketNumber packet_number,
394 bool should_include_version,
395 bool fin,
396 QuicStreamOffset offset,
397 base::StringPiece data) {
398 return InnerConstructDataPacket(packet_number, stream_id_,
399 should_include_version, fin, offset, data,
400 &server_maker_);
ckrasic3865ee0f2016-02-29 22:04:56401 }
402
danakjad1777e2016-04-16 00:56:42403 std::unique_ptr<QuicReceivedPacket> InnerConstructRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56404 QuicPacketNumber packet_number,
405 QuicStreamId stream_id,
406 bool should_include_version,
407 bool fin,
408 RequestPriority request_priority,
xunjieli100937eb52016-09-15 20:09:37409 size_t* spdy_headers_frame_length,
410 QuicStreamOffset* offset) {
ckrasic3865ee0f2016-02-29 22:04:56411 SpdyPriority priority =
412 ConvertRequestPriorityToQuicPriority(request_priority);
alyssar2adf3ac2016-05-03 17:12:58413 return client_maker_.MakeRequestHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56414 packet_number, stream_id, should_include_version, fin, priority,
xunjieli100937eb52016-09-15 20:09:37415 std::move(request_headers_), spdy_headers_frame_length, offset);
[email protected]f702d572012-12-04 15:56:20416 }
417
danakjad1777e2016-04-16 00:56:42418 std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
rtennetia004d332015-08-28 06:44:57419 QuicPacketNumber packet_number,
rtennetif4bdb542015-01-21 14:33:05420 bool fin,
sclittlec4dc1a32015-09-24 00:15:45421 RequestPriority request_priority,
422 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56423 return InnerConstructRequestHeadersPacket(
424 packet_number, stream_id_, kIncludeVersion, fin, request_priority,
xunjieli100937eb52016-09-15 20:09:37425 spdy_headers_frame_length, nullptr);
ckrasic3865ee0f2016-02-29 22:04:56426 }
427
danakjad1777e2016-04-16 00:56:42428 std::unique_ptr<QuicReceivedPacket> InnerConstructResponseHeadersPacket(
ckrasic3865ee0f2016-02-29 22:04:56429 QuicPacketNumber packet_number,
430 QuicStreamId stream_id,
431 bool fin,
432 size_t* spdy_headers_frame_length) {
alyssar2adf3ac2016-05-03 17:12:58433 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26434 packet_number, stream_id, !kIncludeVersion, fin,
435 std::move(response_headers_), spdy_headers_frame_length,
436 &response_offset_);
[email protected]1e960032013-12-20 19:00:20437 }
438
danakjad1777e2016-04-16 00:56:42439 std::unique_ptr<QuicReceivedPacket> ConstructResponseHeadersPacket(
rtennetia004d332015-08-28 06:44:57440 QuicPacketNumber packet_number,
sclittlec4dc1a32015-09-24 00:15:45441 bool fin,
442 size_t* spdy_headers_frame_length) {
ckrasic3865ee0f2016-02-29 22:04:56443 return InnerConstructResponseHeadersPacket(packet_number, stream_id_, fin,
444 spdy_headers_frame_length);
[email protected]1e960032013-12-20 19:00:20445 }
446
danakjad1777e2016-04-16 00:56:42447 std::unique_ptr<QuicReceivedPacket> ConstructResponseHeadersPacketWithOffset(
xunjieli34291fe12016-03-02 13:58:38448 QuicPacketNumber packet_number,
449 bool fin,
450 size_t* spdy_headers_frame_length,
451 QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58452 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26453 packet_number, stream_id_, !kIncludeVersion, fin,
454 std::move(response_headers_), spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38455 }
456
danakjad1777e2016-04-16 00:56:42457 std::unique_ptr<QuicReceivedPacket> ConstructResponseTrailersPacket(
xunjieli34291fe12016-03-02 13:58:38458 QuicPacketNumber packet_number,
459 bool fin,
bnc086b39e12016-06-24 13:05:26460 SpdyHeaderBlock trailers,
xunjieli34291fe12016-03-02 13:58:38461 size_t* spdy_headers_frame_length,
462 QuicStreamOffset* offset) {
alyssar2adf3ac2016-05-03 17:12:58463 return server_maker_.MakeResponseHeadersPacket(
bnc086b39e12016-06-24 13:05:26464 packet_number, stream_id_, !kIncludeVersion, fin, std::move(trailers),
alyssar2adf3ac2016-05-03 17:12:58465 spdy_headers_frame_length, offset);
xunjieli34291fe12016-03-02 13:58:38466 }
467
alyssar2adf3ac2016-05-03 17:12:58468 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamPacket(
rtennetia004d332015-08-28 06:44:57469 QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58470 return client_maker_.MakeRstPacket(
rtennetia004d332015-08-28 06:44:57471 packet_number, true, stream_id_,
rtenneti4a5df262014-11-07 00:43:58472 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
[email protected]06ff5152013-08-29 01:03:05473 }
474
alyssar2adf3ac2016-05-03 17:12:58475 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamCancelledPacket(
rtennetia004d332015-08-28 06:44:57476 QuicPacketNumber packet_number) {
alyssar2adf3ac2016-05-03 17:12:58477 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
478 stream_id_, QUIC_STREAM_CANCELLED);
rtenneti6bd660b2015-07-18 00:19:53479 }
480
alyssar2adf3ac2016-05-03 17:12:58481 std::unique_ptr<QuicReceivedPacket>
482 ConstructClientRstStreamVaryMismatchPacket(QuicPacketNumber packet_number) {
483 return client_maker_.MakeRstPacket(packet_number, !kIncludeVersion,
484 promise_id_, QUIC_PROMISE_VARY_MISMATCH);
ckrasic3865ee0f2016-02-29 22:04:56485 }
486
danakjad1777e2016-04-16 00:56:42487 std::unique_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
xunjieli34291fe12016-03-02 13:58:38488 QuicPacketNumber packet_number,
489 QuicPacketNumber largest_received,
490 QuicPacketNumber ack_least_unacked,
491 QuicPacketNumber stop_least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58492 return client_maker_.MakeAckAndRstPacket(
xunjieli34291fe12016-03-02 13:58:38493 packet_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
494 largest_received, ack_least_unacked, stop_least_unacked,
495 !kIncludeCongestionFeedback);
496 }
497
maksim.sisov84e20c92016-06-23 08:49:34498 std::unique_ptr<QuicReceivedPacket> ConstructClientRstStreamErrorPacket(
499 QuicPacketNumber packet_number,
500 bool include_version) {
501 return client_maker_.MakeRstPacket(packet_number, include_version,
502 stream_id_,
503 QUIC_ERROR_PROCESSING_STREAM);
504 }
505
danakjad1777e2016-04-16 00:56:42506 std::unique_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
rtennetia004d332015-08-28 06:44:57507 QuicPacketNumber packet_number) {
xunjieli34291fe12016-03-02 13:58:38508 return ConstructAckAndRstStreamPacket(packet_number, 2, 1, 1);
[email protected]c5e1aca2014-01-30 04:03:04509 }
510
alyssar2adf3ac2016-05-03 17:12:58511 std::unique_ptr<QuicReceivedPacket> ConstructClientAckPacket(
rtennetia004d332015-08-28 06:44:57512 QuicPacketNumber packet_number,
513 QuicPacketNumber largest_received,
514 QuicPacketNumber least_unacked) {
alyssar2adf3ac2016-05-03 17:12:58515 return client_maker_.MakeAckPacket(packet_number, largest_received,
516 least_unacked,
517 !kIncludeCongestionFeedback);
518 }
519
520 std::unique_ptr<QuicReceivedPacket> ConstructServerAckPacket(
521 QuicPacketNumber packet_number,
522 QuicPacketNumber largest_received,
523 QuicPacketNumber least_unacked) {
524 return server_maker_.MakeAckPacket(packet_number, largest_received,
525 least_unacked,
526 !kIncludeCongestionFeedback);
[email protected]63534512012-12-23 18:49:00527 }
528
ckrasic3865ee0f2016-02-29 22:04:56529 void ReceivePromise(QuicStreamId id) {
530 QuicChromiumClientStream* stream =
531 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
532 stream->OnStreamHeaders(serialized_push_promise_);
533
534 stream->OnPromiseHeadersComplete(id, serialized_push_promise_.size());
535 }
536
xunjieli84adaab2016-09-20 01:12:28537 void ExpectLoadTimingValid(const LoadTimingInfo& load_timing_info,
xunjieli100937eb52016-09-15 20:09:37538 bool session_reused) {
539 EXPECT_EQ(session_reused, load_timing_info.socket_reused);
xunjieli84adaab2016-09-20 01:12:28540 if (session_reused) {
541 ExpectConnectTimingHasNoTimes(load_timing_info.connect_timing);
542 } else {
543 ExpectConnectTimingHasTimes(
544 load_timing_info.connect_timing,
545 CONNECT_TIMING_HAS_SSL_TIMES | CONNECT_TIMING_HAS_DNS_TIMES);
546 }
547 ExpectLoadTimingHasOnlyConnectionTimes(load_timing_info);
xunjieli100937eb52016-09-15 20:09:37548 }
549
xunjieli5fafe142016-03-23 23:32:54550 BoundTestNetLog net_log_;
[email protected]63534512012-12-23 18:49:00551 bool use_closing_stream_;
[email protected]fee17f72013-02-03 07:47:41552 MockSendAlgorithm* send_algorithm_;
[email protected]f702d572012-12-04 15:56:20553 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42554 std::unique_ptr<MockWrite[]> mock_writes_;
[email protected]f702d572012-12-04 15:56:20555 MockClock clock_;
556 TestQuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42557 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07558 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
ckrasica7fd1242016-05-14 20:36:01559 testing::StrictMock<MockQuicConnectionVisitor> visitor_;
danakjad1777e2016-04-16 00:56:42560 std::unique_ptr<QuicHttpStream> stream_;
[email protected]5db452202014-08-19 05:22:15561 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42562 std::unique_ptr<QuicChromiumClientSession> session_;
[email protected]ef95114d2013-04-17 17:57:01563 QuicCryptoClientConfig crypto_config_;
[email protected]f702d572012-12-04 15:56:20564 TestCompletionCallback callback_;
565 HttpRequestInfo request_;
566 HttpRequestHeaders headers_;
567 HttpResponseInfo response_;
568 scoped_refptr<IOBufferWithSize> read_buffer_;
[email protected]1e960032013-12-20 19:00:20569 SpdyHeaderBlock request_headers_;
570 SpdyHeaderBlock response_headers_;
bnc614a92d32016-04-04 13:56:07571 string request_data_;
572 string response_data_;
ckrasic244375a32016-02-04 21:21:22573 QuicClientPushPromiseIndex push_promise_index_;
[email protected]f702d572012-12-04 15:56:20574
ckrasic3865ee0f2016-02-29 22:04:56575 // For server push testing
danakjad1777e2016-04-16 00:56:42576 std::unique_ptr<QuicHttpStream> promised_stream_;
ckrasic3865ee0f2016-02-29 22:04:56577 SpdyHeaderBlock push_promise_;
578 SpdyHeaderBlock promised_response_;
579 const QuicStreamId promise_id_;
580 string promise_url_;
581 string serialized_push_promise_;
582 const QuicStreamId stream_id_;
583
[email protected]3aa9ca72014-02-27 19:39:43584 const QuicConnectionId connection_id_;
alyssar2adf3ac2016-05-03 17:12:58585 QuicTestPacketMaker client_maker_;
586 QuicTestPacketMaker server_maker_;
[email protected]f702d572012-12-04 15:56:20587 IPEndPoint self_addr_;
588 IPEndPoint peer_addr_;
[email protected]457d6952013-12-13 09:24:58589 MockRandom random_generator_;
rch03b7a202016-02-05 00:54:20590 ProofVerifyDetailsChromium verify_details_;
[email protected]e8ff26842013-03-22 21:02:05591 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42592 std::unique_ptr<StaticSocketDataProvider> socket_data_;
[email protected]f702d572012-12-04 15:56:20593 std::vector<PacketToWrite> writes_;
ckrasic3865ee0f2016-02-29 22:04:56594 QuicStreamOffset response_offset_;
[email protected]f702d572012-12-04 15:56:20595};
596
rjshaded5ced072015-12-18 19:26:02597INSTANTIATE_TEST_CASE_P(Version,
598 QuicHttpStreamTest,
danzh3134c2562016-08-12 14:07:52599 ::testing::ValuesIn(AllSupportedVersions()));
[email protected]1e960032013-12-20 19:00:20600
601TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
[email protected]ed3fc15d2013-03-08 18:37:44602 Initialize();
rtennetibe635732014-10-02 22:51:42603 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
[email protected]f702d572012-12-04 15:56:20604}
605
mmenkebd84c392015-09-02 14:12:34606TEST_P(QuicHttpStreamTest, CanReuseConnection) {
[email protected]ed3fc15d2013-03-08 18:37:44607 Initialize();
mmenkebd84c392015-09-02 14:12:34608 EXPECT_FALSE(stream_->CanReuseConnection());
[email protected]f702d572012-12-04 15:56:20609}
610
jri231c2972016-03-08 19:50:11611TEST_P(QuicHttpStreamTest, DisableConnectionMigrationForStream) {
612 request_.load_flags |= LOAD_DISABLE_CONNECTION_MIGRATION;
613 Initialize();
xunjieli5fafe142016-03-23 23:32:54614 EXPECT_EQ(OK,
615 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
616 net_log_.bound(), callback_.callback()));
jri231c2972016-03-08 19:50:11617 QuicChromiumClientStream* client_stream =
618 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
619 EXPECT_FALSE(client_stream->can_migrate());
620}
621
[email protected]1e960032013-12-20 19:00:20622TEST_P(QuicHttpStreamTest, GetRequest) {
623 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45624 size_t spdy_request_header_frame_length;
625 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
626 &spdy_request_header_frame_length));
[email protected]f702d572012-12-04 15:56:20627 Initialize();
628
629 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29630 request_.url = GURL("http://www.example.org/");
[email protected]f702d572012-12-04 15:56:20631
xunjieli100937eb52016-09-15 20:09:37632 // Make sure getting load timing from the stream early does not crash.
633 LoadTimingInfo load_timing_info;
634 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
635
xunjieli5fafe142016-03-23 23:32:54636 EXPECT_EQ(OK,
637 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
638 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02639 EXPECT_EQ(OK,
640 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:20641
642 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:58643 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:20644
robpercival214763f2016-07-01 23:27:01645 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
646 IsError(ERR_IO_PENDING));
[email protected]f702d572012-12-04 15:56:20647
bnc614a92d32016-04-04 13:56:07648 SetResponse("404 Not Found", string());
sclittlec4dc1a32015-09-24 00:15:45649 size_t spdy_response_header_frame_length;
650 ProcessPacket(ConstructResponseHeadersPacket(
651 2, kFin, &spdy_response_header_frame_length));
[email protected]f702d572012-12-04 15:56:20652
653 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01654 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:36655 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:20656 EXPECT_EQ(404, response_.headers->response_code());
657 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
[email protected]6ed67432014-06-24 01:53:53658 EXPECT_FALSE(response_.response_time.is_null());
659 EXPECT_FALSE(response_.request_time.is_null());
[email protected]f702d572012-12-04 15:56:20660
661 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02662 EXPECT_EQ(0,
663 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
664 callback_.callback()));
[email protected]f702d572012-12-04 15:56:20665 EXPECT_TRUE(stream_->IsResponseBodyComplete());
666 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10667
xunjieli100937eb52016-09-15 20:09:37668 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28669 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37670
sclittle1edeeb22015-09-02 20:46:10671 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45672 // headers and payload.
673 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
674 stream_->GetTotalSentBytes());
675 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
676 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:20677}
678
xunjieli100937eb52016-09-15 20:09:37679TEST_P(QuicHttpStreamTest, LoadTimingTwoRequests) {
680 SetRequest("GET", "/", DEFAULT_PRIORITY);
681 size_t spdy_request_header_frame_length;
682
683 QuicStreamOffset offset = 0;
684 AddWrite(InnerConstructRequestHeadersPacket(
685 1, kClientDataStreamId1, kIncludeVersion, kFin, DEFAULT_PRIORITY,
686 &spdy_request_header_frame_length, &offset));
687
688 // SetRequest() again for second request as |request_headers_| was moved.
689 SetRequest("GET", "/", DEFAULT_PRIORITY);
690 AddWrite(InnerConstructRequestHeadersPacket(
691 2, kClientDataStreamId2, kIncludeVersion, kFin, DEFAULT_PRIORITY,
692 &spdy_request_header_frame_length, &offset));
693 AddWrite(ConstructClientAckPacket(3, 3, 1)); // Ack the responses.
694
695 Initialize();
696
697 request_.method = "GET";
698 request_.url = GURL("http://www.example.org/");
699 // Start first request.
700 EXPECT_EQ(OK,
701 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
702 net_log_.bound(), callback_.callback()));
703 EXPECT_EQ(OK,
704 stream_->SendRequest(headers_, &response_, callback_.callback()));
705
706 // Start a second request.
707 QuicHttpStream stream2(session_->GetWeakPtr());
708 TestCompletionCallback callback2;
709 EXPECT_EQ(OK,
710 stream2.InitializeStream(&request_, DEFAULT_PRIORITY,
711 net_log_.bound(), callback2.callback()));
712 EXPECT_EQ(OK,
713 stream2.SendRequest(headers_, &response_, callback2.callback()));
714
715 // Ack both requests.
716 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
717
718 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
719 IsError(ERR_IO_PENDING));
720 size_t spdy_response_header_frame_length;
721 SetResponse("200 OK", string());
722 ProcessPacket(InnerConstructResponseHeadersPacket(
723 2, kClientDataStreamId1, kFin, &spdy_response_header_frame_length));
724
725 // Now that the headers have been processed, the callback will return.
726 EXPECT_THAT(callback_.WaitForResult(), IsOk());
727 EXPECT_EQ(200, response_.headers->response_code());
728
729 // There is no body, so this should return immediately.
730 EXPECT_EQ(0,
731 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
732 callback_.callback()));
733 EXPECT_TRUE(stream_->IsResponseBodyComplete());
734
735 LoadTimingInfo load_timing_info;
736 EXPECT_TRUE(stream_->GetLoadTimingInfo(&load_timing_info));
xunjieli84adaab2016-09-20 01:12:28737 ExpectLoadTimingValid(load_timing_info, /*session_reused=*/false);
xunjieli100937eb52016-09-15 20:09:37738
739 // SetResponse() again for second request as |response_headers_| was moved.
740 SetResponse("200 OK", string());
741 EXPECT_THAT(stream2.ReadResponseHeaders(callback2.callback()),
742 IsError(ERR_IO_PENDING));
743
744 ProcessPacket(InnerConstructResponseHeadersPacket(
745 3, kClientDataStreamId2, kFin, &spdy_response_header_frame_length));
746
747 EXPECT_THAT(callback2.WaitForResult(), IsOk());
748
749 // There is no body, so this should return immediately.
750 EXPECT_EQ(0,
751 stream2.ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
752 callback2.callback()));
753 EXPECT_TRUE(stream2.IsResponseBodyComplete());
754
755 LoadTimingInfo load_timing_info2;
756 EXPECT_TRUE(stream2.GetLoadTimingInfo(&load_timing_info2));
xunjieli84adaab2016-09-20 01:12:28757 ExpectLoadTimingValid(load_timing_info2, /*session_reused=*/true);
xunjieli100937eb52016-09-15 20:09:37758}
759
xunjieli34291fe12016-03-02 13:58:38760// QuicHttpStream does not currently support trailers. It should ignore
761// trailers upon receiving them.
762TEST_P(QuicHttpStreamTest, GetRequestWithTrailers) {
763 SetRequest("GET", "/", DEFAULT_PRIORITY);
764 size_t spdy_request_header_frame_length;
765 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
766 &spdy_request_header_frame_length));
alyssar2adf3ac2016-05-03 17:12:58767 AddWrite(ConstructClientAckPacket(2, 3, 1)); // Ack the data packet.
xunjieli34291fe12016-03-02 13:58:38768
769 Initialize();
770
771 request_.method = "GET";
772 request_.url = GURL("http://www.example.org/");
773
xunjieli5fafe142016-03-23 23:32:54774 EXPECT_EQ(OK,
775 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
776 net_log_.bound(), callback_.callback()));
777
xunjieli34291fe12016-03-02 13:58:38778 EXPECT_EQ(OK,
779 stream_->SendRequest(headers_, &response_, callback_.callback()));
xunjieli34291fe12016-03-02 13:58:38780 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:58781 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
xunjieli34291fe12016-03-02 13:58:38782
robpercival214763f2016-07-01 23:27:01783 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
784 IsError(ERR_IO_PENDING));
xunjieli34291fe12016-03-02 13:58:38785
bnc614a92d32016-04-04 13:56:07786 SetResponse("200 OK", string());
xunjieli34291fe12016-03-02 13:58:38787
788 // Send the response headers.
789 size_t spdy_response_header_frame_length;
790 QuicStreamOffset offset = 0;
791 ProcessPacket(ConstructResponseHeadersPacketWithOffset(
792 2, !kFin, &spdy_response_header_frame_length, &offset));
793 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01794 EXPECT_THAT(callback_.WaitForResult(), IsOk());
xunjieli34291fe12016-03-02 13:58:38795 ASSERT_TRUE(response_.headers.get());
796 EXPECT_EQ(200, response_.headers->response_code());
797 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
798 EXPECT_FALSE(response_.response_time.is_null());
799 EXPECT_FALSE(response_.request_time.is_null());
800
801 // Send the response body.
802 const char kResponseBody[] = "Hello world!";
803 ProcessPacket(
alyssar2adf3ac2016-05-03 17:12:58804 ConstructServerDataPacket(3, false, !kFin, /*offset=*/0, kResponseBody));
xunjieli34291fe12016-03-02 13:58:38805 SpdyHeaderBlock trailers;
806 size_t spdy_trailers_frame_length;
807 trailers["foo"] = "bar";
xunjieli188bd402016-03-12 00:17:25808 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
xunjieli34291fe12016-03-02 13:58:38809 ProcessPacket(ConstructResponseTrailersPacket(
bnc086b39e12016-06-24 13:05:26810 4, kFin, std::move(trailers), &spdy_trailers_frame_length, &offset));
xunjieli34291fe12016-03-02 13:58:38811
812 // Make sure trailers are processed.
fdoray92e35a72016-06-10 15:54:55813 base::RunLoop().RunUntilIdle();
xunjieli34291fe12016-03-02 13:58:38814
815 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
816 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
817 callback_.callback()));
818 EXPECT_TRUE(stream_->IsResponseBodyComplete());
819
820 EXPECT_EQ(OK,
821 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
822 callback_.callback()));
823
824 EXPECT_TRUE(stream_->IsResponseBodyComplete());
825 EXPECT_TRUE(AtEof());
826
827 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
828 // headers and payload.
829 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
830 stream_->GetTotalSentBytes());
831 EXPECT_EQ(
832 static_cast<int64_t>(spdy_response_header_frame_length +
833 strlen(kResponseBody) + +spdy_trailers_frame_length),
834 stream_->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54835 // Check that NetLog was filled as expected.
836 TestNetLogEntry::List entries;
837 net_log_.GetEntries(&entries);
838 size_t pos = ExpectLogContainsSomewhere(
839 entries, /*min_offset=*/0,
mikecirone8b85c432016-09-08 19:11:00840 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
841 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54842 pos = ExpectLogContainsSomewhere(
843 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00844 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
845 NetLogEventPhase::NONE);
xunjieli5fafe142016-03-23 23:32:54846 ExpectLogContainsSomewhere(
847 entries, /*min_offset=*/pos,
mikecirone8b85c432016-09-08 19:11:00848 NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
849 NetLogEventPhase::NONE);
xunjieli34291fe12016-03-02 13:58:38850}
851
[email protected]3e7dca62013-09-10 16:14:23852// Regression test for http://crbug.com/288128
[email protected]1e960032013-12-20 19:00:20853TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
854 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:45855 size_t spdy_request_headers_frame_length;
856 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
857 &spdy_request_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23858 Initialize();
859
860 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29861 request_.url = GURL("http://www.example.org/");
[email protected]3e7dca62013-09-10 16:14:23862
xunjieli5fafe142016-03-23 23:32:54863 EXPECT_EQ(OK,
864 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
865 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:02866 EXPECT_EQ(OK,
867 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23868
869 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:58870 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]3e7dca62013-09-10 16:14:23871
robpercival214763f2016-07-01 23:27:01872 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
873 IsError(ERR_IO_PENDING));
[email protected]3e7dca62013-09-10 16:14:23874
bnc086b39e12016-06-24 13:05:26875 response_headers_[":status"] = "200 OK";
876 response_headers_[":version"] = "HTTP/1.1";
877 response_headers_["content-type"] = "text/plain";
878 response_headers_["big6"] = string(1000, 'x'); // Lots of x's.
[email protected]3e7dca62013-09-10 16:14:23879
sclittlec4dc1a32015-09-24 00:15:45880 size_t spdy_response_headers_frame_length;
881 ProcessPacket(ConstructResponseHeadersPacket(
882 2, kFin, &spdy_response_headers_frame_length));
[email protected]3e7dca62013-09-10 16:14:23883
884 // Now that the headers have been processed, the callback will return.
robpercival214763f2016-07-01 23:27:01885 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]3e7dca62013-09-10 16:14:23886 ASSERT_TRUE(response_.headers.get());
887 EXPECT_EQ(200, response_.headers->response_code());
888 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
889
890 // There is no body, so this should return immediately.
rjshaded5ced072015-12-18 19:26:02891 EXPECT_EQ(0,
892 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
893 callback_.callback()));
[email protected]3e7dca62013-09-10 16:14:23894 EXPECT_TRUE(stream_->IsResponseBodyComplete());
895 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:10896
897 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:45898 // headers and payload.
899 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
900 stream_->GetTotalSentBytes());
901 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
902 stream_->GetTotalReceivedBytes());
[email protected]3e7dca62013-09-10 16:14:23903}
904
rchf9f103cbc2014-08-30 05:28:04905// Regression test for http://crbug.com/409101
906TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
907 SetRequest("GET", "/", DEFAULT_PRIORITY);
908 Initialize();
909
910 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29911 request_.url = GURL("http://www.example.org/");
rchf9f103cbc2014-08-30 05:28:04912
xunjieli5fafe142016-03-23 23:32:54913 EXPECT_EQ(OK,
914 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
915 net_log_.bound(), callback_.callback()));
rchf9f103cbc2014-08-30 05:28:04916
jri78ec06a2016-03-31 18:19:40917 session_->connection()->CloseConnection(
918 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rchf9f103cbc2014-08-30 05:28:04919
920 EXPECT_EQ(ERR_CONNECTION_CLOSED,
rjshaded5ced072015-12-18 19:26:02921 stream_->SendRequest(headers_, &response_, callback_.callback()));
sclittle1edeeb22015-09-02 20:46:10922
923 EXPECT_EQ(0, stream_->GetTotalSentBytes());
924 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rchf9f103cbc2014-08-30 05:28:04925}
926
rch03b7a202016-02-05 00:54:20927// Regression test for http://crbug.com/584441
928TEST_P(QuicHttpStreamTest, GetSSLInfoAfterSessionClosed) {
929 SetRequest("GET", "/", DEFAULT_PRIORITY);
930 Initialize();
931
932 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29933 request_.url = GURL("http://www.example.org/");
rch03b7a202016-02-05 00:54:20934
xunjieli5fafe142016-03-23 23:32:54935 EXPECT_EQ(OK,
936 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
937 net_log_.bound(), callback_.callback()));
rch03b7a202016-02-05 00:54:20938
939 SSLInfo ssl_info;
rch11565e02016-02-09 20:13:47940 EXPECT_FALSE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20941 stream_->GetSSLInfo(&ssl_info);
rch11565e02016-02-09 20:13:47942 EXPECT_TRUE(ssl_info.is_valid());
rch03b7a202016-02-05 00:54:20943
jri78ec06a2016-03-31 18:19:40944 session_->connection()->CloseConnection(
945 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch03b7a202016-02-05 00:54:20946
rch11565e02016-02-09 20:13:47947 SSLInfo ssl_info2;
948 stream_->GetSSLInfo(&ssl_info2);
949 EXPECT_TRUE(ssl_info2.is_valid());
rch03b7a202016-02-05 00:54:20950}
951
zhongyica364fbb2015-12-12 03:39:12952TEST_P(QuicHttpStreamTest, LogGranularQuicConnectionError) {
953 SetRequest("GET", "/", DEFAULT_PRIORITY);
954 size_t spdy_request_headers_frame_length;
955 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
956 &spdy_request_headers_frame_length));
957 AddWrite(ConstructAckAndRstStreamPacket(2));
958 use_closing_stream_ = true;
959 Initialize();
960
961 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29962 request_.url = GURL("http://www.example.org/");
zhongyica364fbb2015-12-12 03:39:12963
xunjieli5fafe142016-03-23 23:32:54964 EXPECT_EQ(OK,
965 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
966 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:12967 EXPECT_EQ(OK,
968 stream_->SendRequest(headers_, &response_, callback_.callback()));
969
970 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:58971 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
robpercival214763f2016-07-01 23:27:01972 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
973 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:12974
975 EXPECT_TRUE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
rch1c5b74a2016-06-23 22:10:55976
977 QuicConnectionCloseFrame frame;
978 frame.error_code = QUIC_PEER_GOING_AWAY;
979 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:12980
981 NetErrorDetails details;
982 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
983 stream_->PopulateNetErrorDetails(&details);
984 EXPECT_EQ(QUIC_PEER_GOING_AWAY, details.quic_connection_error);
985}
986
987TEST_P(QuicHttpStreamTest, DoNotLogGranularQuicErrorIfHandshakeNotConfirmed) {
988 SetRequest("GET", "/", DEFAULT_PRIORITY);
989 size_t spdy_request_headers_frame_length;
990 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
991 &spdy_request_headers_frame_length));
992 AddWrite(ConstructAckAndRstStreamPacket(2));
993 use_closing_stream_ = true;
994 Initialize();
995
996 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:29997 request_.url = GURL("http://www.example.org/");
zhongyica364fbb2015-12-12 03:39:12998
xunjieli5fafe142016-03-23 23:32:54999 EXPECT_EQ(OK,
1000 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1001 net_log_.bound(), callback_.callback()));
zhongyica364fbb2015-12-12 03:39:121002 EXPECT_EQ(OK,
1003 stream_->SendRequest(headers_, &response_, callback_.callback()));
1004
1005 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:581006 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
robpercival214763f2016-07-01 23:27:011007 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1008 IsError(ERR_IO_PENDING));
zhongyica364fbb2015-12-12 03:39:121009
1010 // The test setup defaults handshake to be confirmed. Manually set
1011 // it to be not confirmed.
1012 // Granular errors shouldn't be reported if handshake not confirmed.
1013 QuicHttpStreamPeer::SetHandshakeConfirmed(stream_.get(), false);
1014
1015 EXPECT_FALSE(QuicHttpStreamPeer::WasHandshakeConfirmed(stream_.get()));
rch1c5b74a2016-06-23 22:10:551016 QuicConnectionCloseFrame frame;
1017 frame.error_code = QUIC_PEER_GOING_AWAY;
1018 session_->connection()->OnConnectionCloseFrame(frame);
zhongyica364fbb2015-12-12 03:39:121019
1020 NetErrorDetails details;
1021 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
1022 stream_->PopulateNetErrorDetails(&details);
1023 EXPECT_EQ(QUIC_NO_ERROR, details.quic_connection_error);
1024}
1025
rch11a114a2014-09-04 23:41:591026// Regression test for http://crbug.com/409871
1027TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
1028 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451029 size_t spdy_request_headers_frame_length;
1030 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
1031 &spdy_request_headers_frame_length));
rch11a114a2014-09-04 23:41:591032 Initialize();
1033
1034 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:291035 request_.url = GURL("http://www.example.org/");
rch11a114a2014-09-04 23:41:591036
xunjieli5fafe142016-03-23 23:32:541037 EXPECT_EQ(OK,
1038 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1039 net_log_.bound(), callback_.callback()));
rch11a114a2014-09-04 23:41:591040
rjshaded5ced072015-12-18 19:26:021041 EXPECT_EQ(OK,
1042 stream_->SendRequest(headers_, &response_, callback_.callback()));
rch11a114a2014-09-04 23:41:591043
jri78ec06a2016-03-31 18:19:401044 session_->connection()->CloseConnection(
1045 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
rch11a114a2014-09-04 23:41:591046
1047 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
sclittle1edeeb22015-09-02 20:46:101048
1049 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451050 // headers and payload.
1051 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1052 stream_->GetTotalSentBytes());
sclittle1edeeb22015-09-02 20:46:101053 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
rch11a114a2014-09-04 23:41:591054}
1055
[email protected]1e960032013-12-20 19:00:201056TEST_P(QuicHttpStreamTest, SendPostRequest) {
1057 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451058 size_t spdy_request_headers_frame_length;
1059 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1060 &spdy_request_headers_frame_length));
alyssar2adf3ac2016-05-03 17:12:581061 AddWrite(ConstructClientDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
1062 AddWrite(ConstructClientAckPacket(3, 3, 1));
[email protected]f702d572012-12-04 15:56:201063
1064 Initialize();
1065
danakjad1777e2016-04-16 00:56:421066 std::vector<std::unique_ptr<UploadElementReader>> element_readers;
ricea2deef682016-09-09 08:04:071067 element_readers.push_back(base::MakeUnique<UploadBytesElementReader>(
1068 kUploadData, strlen(kUploadData)));
olli.raula6df48b2a2015-11-26 07:40:221069 ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0);
[email protected]f702d572012-12-04 15:56:201070 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291071 request_.url = GURL("http://www.example.org/");
[email protected]f702d572012-12-04 15:56:201072 request_.upload_data_stream = &upload_data_stream;
maksim.sisov819ba852016-08-17 08:22:521073 ASSERT_THAT(
1074 request_.upload_data_stream->Init(CompletionCallback(), BoundNetLog()),
1075 IsOk());
[email protected]f702d572012-12-04 15:56:201076
xunjieli5fafe142016-03-23 23:32:541077 EXPECT_EQ(OK,
1078 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1079 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021080 EXPECT_EQ(OK,
1081 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]f702d572012-12-04 15:56:201082
1083 // Ack both packets in the request.
alyssar2adf3ac2016-05-03 17:12:581084 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]f702d572012-12-04 15:56:201085
1086 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071087 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451088 size_t spdy_response_headers_frame_length;
1089 ProcessPacket(ConstructResponseHeadersPacket(
1090 2, !kFin, &spdy_response_headers_frame_length));
[email protected]f702d572012-12-04 15:56:201091
rchb27683c2015-07-29 23:53:501092 // The headers have arrived, but they are delivered asynchronously.
robpercival214763f2016-07-01 23:27:011093 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1094 IsError(ERR_IO_PENDING));
1095 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:361096 ASSERT_TRUE(response_.headers.get());
[email protected]f702d572012-12-04 15:56:201097 EXPECT_EQ(200, response_.headers->response_code());
1098 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1099
1100 // Send the response body.
1101 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581102 ProcessPacket(ConstructServerDataPacket(3, false, kFin, 0, kResponseBody));
[email protected]f702d572012-12-04 15:56:201103 // Since the body has already arrived, this should return immediately.
1104 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
1105 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1106 callback_.callback()));
1107
1108 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1109 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101110
1111 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451112 // headers and payload.
1113 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1114 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101115 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451116 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1117 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101118 stream_->GetTotalReceivedBytes());
[email protected]f702d572012-12-04 15:56:201119}
1120
[email protected]1e960032013-12-20 19:00:201121TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
1122 SetRequest("POST", "/", DEFAULT_PRIORITY);
[email protected]c9e49a02013-02-26 05:56:471123 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451124 size_t spdy_request_headers_frame_length;
1125 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1126 &spdy_request_headers_frame_length));
rjshaded5ced072015-12-18 19:26:021127 AddWrite(
alyssar2adf3ac2016-05-03 17:12:581128 ConstructClientDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
1129 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size,
1130 kUploadData));
1131 AddWrite(ConstructClientAckPacket(4, 3, 1));
[email protected]c9e49a02013-02-26 05:56:471132 Initialize();
1133
mmenkecbc2b712014-10-09 20:29:071134 ChunkedUploadDataStream upload_data_stream(0);
1135 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]c9e49a02013-02-26 05:56:471136
1137 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291138 request_.url = GURL("http://www.example.org/");
[email protected]c9e49a02013-02-26 05:56:471139 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:071140 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521141 TestCompletionCallback().callback(), BoundNetLog()));
[email protected]c9e49a02013-02-26 05:56:471142
xunjieli5fafe142016-03-23 23:32:541143 ASSERT_EQ(OK,
1144 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1145 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021146 ASSERT_EQ(ERR_IO_PENDING,
1147 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]c9e49a02013-02-26 05:56:471148
mmenkecbc2b712014-10-09 20:29:071149 upload_data_stream.AppendData(kUploadData, chunk_size, true);
robpercival214763f2016-07-01 23:27:011150 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]c9e49a02013-02-26 05:56:471151
1152 // Ack both packets in the request.
alyssar2adf3ac2016-05-03 17:12:581153 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]c9e49a02013-02-26 05:56:471154
1155 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071156 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451157 size_t spdy_response_headers_frame_length;
1158 ProcessPacket(ConstructResponseHeadersPacket(
1159 2, !kFin, &spdy_response_headers_frame_length));
[email protected]c9e49a02013-02-26 05:56:471160
rchb27683c2015-07-29 23:53:501161 // The headers have arrived, but they are delivered asynchronously
robpercival214763f2016-07-01 23:27:011162 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1163 IsError(ERR_IO_PENDING));
1164 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]cadac622013-06-11 16:46:361165 ASSERT_TRUE(response_.headers.get());
[email protected]c9e49a02013-02-26 05:56:471166 EXPECT_EQ(200, response_.headers->response_code());
1167 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1168
1169 // Send the response body.
1170 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581171 ProcessPacket(ConstructServerDataPacket(
1172 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]c9e49a02013-02-26 05:56:471173
1174 // Since the body has already arrived, this should return immediately.
1175 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1176 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1177 callback_.callback()));
1178
1179 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1180 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101181
1182 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451183 // headers and payload.
1184 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1185 strlen(kUploadData) * 2),
sclittle1edeeb22015-09-02 20:46:101186 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451187 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1188 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101189 stream_->GetTotalReceivedBytes());
[email protected]c9e49a02013-02-26 05:56:471190}
1191
[email protected]16ba7742014-08-22 00:57:251192TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
1193 SetRequest("POST", "/", DEFAULT_PRIORITY);
1194 size_t chunk_size = strlen(kUploadData);
sclittlec4dc1a32015-09-24 00:15:451195 size_t spdy_request_headers_frame_length;
1196 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1197 &spdy_request_headers_frame_length));
alyssar2adf3ac2016-05-03 17:12:581198 AddWrite(
1199 ConstructClientDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
1200 AddWrite(ConstructClientDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
1201 AddWrite(ConstructClientAckPacket(4, 3, 1));
[email protected]16ba7742014-08-22 00:57:251202 Initialize();
1203
mmenkecbc2b712014-10-09 20:29:071204 ChunkedUploadDataStream upload_data_stream(0);
1205 upload_data_stream.AppendData(kUploadData, chunk_size, false);
[email protected]16ba7742014-08-22 00:57:251206
1207 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291208 request_.url = GURL("http://www.example.org/");
[email protected]16ba7742014-08-22 00:57:251209 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:071210 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521211 TestCompletionCallback().callback(), BoundNetLog()));
[email protected]16ba7742014-08-22 00:57:251212
xunjieli5fafe142016-03-23 23:32:541213 ASSERT_EQ(OK,
1214 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1215 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021216 ASSERT_EQ(ERR_IO_PENDING,
1217 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251218
mmenkecbc2b712014-10-09 20:29:071219 upload_data_stream.AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011220 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251221
alyssar2adf3ac2016-05-03 17:12:581222 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]16ba7742014-08-22 00:57:251223
1224 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071225 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451226 size_t spdy_response_headers_frame_length;
1227 ProcessPacket(ConstructResponseHeadersPacket(
1228 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251229
rchb27683c2015-07-29 23:53:501230 // The headers have arrived, but they are delivered asynchronously
robpercival214763f2016-07-01 23:27:011231 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1232 IsError(ERR_IO_PENDING));
1233 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251234 ASSERT_TRUE(response_.headers.get());
1235 EXPECT_EQ(200, response_.headers->response_code());
1236 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1237
1238 // Send the response body.
1239 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581240 ProcessPacket(ConstructServerDataPacket(
1241 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251242
rchb27683c2015-07-29 23:53:501243 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251244 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1245 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1246 callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251247 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1248 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101249
1250 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451251 // headers and payload.
1252 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
1253 strlen(kUploadData)),
sclittle1edeeb22015-09-02 20:46:101254 stream_->GetTotalSentBytes());
sclittlec4dc1a32015-09-24 00:15:451255 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1256 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101257 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251258}
1259
1260TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
1261 SetRequest("POST", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451262 size_t spdy_request_headers_frame_length;
1263 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1264 &spdy_request_headers_frame_length));
alyssar2adf3ac2016-05-03 17:12:581265 AddWrite(ConstructClientDataPacket(2, kIncludeVersion, kFin, 0, ""));
1266 AddWrite(ConstructClientAckPacket(3, 3, 1));
[email protected]16ba7742014-08-22 00:57:251267 Initialize();
1268
mmenkecbc2b712014-10-09 20:29:071269 ChunkedUploadDataStream upload_data_stream(0);
[email protected]16ba7742014-08-22 00:57:251270
1271 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291272 request_.url = GURL("http://www.example.org/");
[email protected]16ba7742014-08-22 00:57:251273 request_.upload_data_stream = &upload_data_stream;
mmenkecbc2b712014-10-09 20:29:071274 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521275 TestCompletionCallback().callback(), BoundNetLog()));
[email protected]16ba7742014-08-22 00:57:251276
xunjieli5fafe142016-03-23 23:32:541277 ASSERT_EQ(OK,
1278 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1279 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021280 ASSERT_EQ(ERR_IO_PENDING,
1281 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]16ba7742014-08-22 00:57:251282
mmenkecbc2b712014-10-09 20:29:071283 upload_data_stream.AppendData(nullptr, 0, true);
robpercival214763f2016-07-01 23:27:011284 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251285
alyssar2adf3ac2016-05-03 17:12:581286 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
[email protected]16ba7742014-08-22 00:57:251287
1288 // Send the response headers (but not the body).
bnc614a92d32016-04-04 13:56:071289 SetResponse("200 OK", string());
sclittlec4dc1a32015-09-24 00:15:451290 size_t spdy_response_headers_frame_length;
1291 ProcessPacket(ConstructResponseHeadersPacket(
1292 2, !kFin, &spdy_response_headers_frame_length));
[email protected]16ba7742014-08-22 00:57:251293
rchb27683c2015-07-29 23:53:501294 // The headers have arrived, but they are delivered asynchronously
robpercival214763f2016-07-01 23:27:011295 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1296 IsError(ERR_IO_PENDING));
1297 EXPECT_THAT(callback_.WaitForResult(), IsOk());
[email protected]16ba7742014-08-22 00:57:251298 ASSERT_TRUE(response_.headers.get());
1299 EXPECT_EQ(200, response_.headers->response_code());
1300 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1301
1302 // Send the response body.
1303 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581304 ProcessPacket(ConstructServerDataPacket(
1305 3, false, kFin, response_data_.length(), kResponseBody));
[email protected]16ba7742014-08-22 00:57:251306
rchb27683c2015-07-29 23:53:501307 // The body has arrived, but it is delivered asynchronously
[email protected]16ba7742014-08-22 00:57:251308 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
1309 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
1310 callback_.callback()));
1311
1312 EXPECT_TRUE(stream_->IsResponseBodyComplete());
1313 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101314
1315 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451316 // headers and payload.
1317 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1318 stream_->GetTotalSentBytes());
1319 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1320 strlen(kResponseBody)),
sclittle1edeeb22015-09-02 20:46:101321 stream_->GetTotalReceivedBytes());
[email protected]16ba7742014-08-22 00:57:251322}
1323
[email protected]1e960032013-12-20 19:00:201324TEST_P(QuicHttpStreamTest, DestroyedEarly) {
1325 SetRequest("GET", "/", DEFAULT_PRIORITY);
sclittlec4dc1a32015-09-24 00:15:451326 size_t spdy_request_headers_frame_length;
1327 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
1328 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:041329 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]63534512012-12-23 18:49:001330 use_closing_stream_ = true;
1331 Initialize();
1332
1333 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:291334 request_.url = GURL("http://www.example.org/");
[email protected]63534512012-12-23 18:49:001335
xunjieli5fafe142016-03-23 23:32:541336 EXPECT_EQ(OK,
1337 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1338 net_log_.bound(), callback_.callback()));
rjshaded5ced072015-12-18 19:26:021339 EXPECT_EQ(OK,
1340 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]63534512012-12-23 18:49:001341
1342 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:581343 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
robpercival214763f2016-07-01 23:27:011344 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1345 IsError(ERR_IO_PENDING));
[email protected]63534512012-12-23 18:49:001346
1347 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201348 SetResponse("404 OK", "hello world!");
[email protected]63534512012-12-23 18:49:001349 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:451350 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]63534512012-12-23 18:49:001351
fdoray92e35a72016-06-10 15:54:551352 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501353
[email protected]63534512012-12-23 18:49:001354 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101355
1356 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451357 // headers and payload.
1358 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1359 stream_->GetTotalSentBytes());
1360 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:101361 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]63534512012-12-23 18:49:001362}
1363
[email protected]1e960032013-12-20 19:00:201364TEST_P(QuicHttpStreamTest, Priority) {
1365 SetRequest("GET", "/", MEDIUM);
sclittlec4dc1a32015-09-24 00:15:451366 size_t spdy_request_headers_frame_length;
1367 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM,
1368 &spdy_request_headers_frame_length));
rtenneti4efd55dd2015-09-18 01:12:041369 AddWrite(ConstructAckAndRstStreamPacket(2));
[email protected]24e5bc52013-09-18 15:36:581370 use_closing_stream_ = true;
1371 Initialize();
1372
1373 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:291374 request_.url = GURL("http://www.example.org/");
[email protected]24e5bc52013-09-18 15:36:581375
xunjieli5fafe142016-03-23 23:32:541376 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_.bound(),
rjshaded5ced072015-12-18 19:26:021377 callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581378
1379 // Check that priority is highest.
rch12fef552016-01-15 16:26:311380 QuicChromiumClientStream* reliable_stream =
1381 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
[email protected]24e5bc52013-09-18 15:36:581382 DCHECK(reliable_stream);
fayanga64c1a92016-02-13 01:55:581383 DCHECK_EQ(kV3HighestPriority, reliable_stream->priority());
[email protected]24e5bc52013-09-18 15:36:581384
rjshaded5ced072015-12-18 19:26:021385 EXPECT_EQ(OK,
1386 stream_->SendRequest(headers_, &response_, callback_.callback()));
[email protected]24e5bc52013-09-18 15:36:581387
1388 // Check that priority has now dropped back to MEDIUM.
ianswett0888cff2015-11-24 17:42:161389 DCHECK_EQ(MEDIUM,
fayanga64c1a92016-02-13 01:55:581390 ConvertQuicPriorityToRequestPriority(reliable_stream->priority()));
[email protected]24e5bc52013-09-18 15:36:581391
1392 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:581393 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
robpercival214763f2016-07-01 23:27:011394 EXPECT_THAT(stream_->ReadResponseHeaders(callback_.callback()),
1395 IsError(ERR_IO_PENDING));
[email protected]24e5bc52013-09-18 15:36:581396
1397 // Send the response with a body.
[email protected]1e960032013-12-20 19:00:201398 SetResponse("404 OK", "hello world!");
[email protected]24e5bc52013-09-18 15:36:581399 // In the course of processing this packet, the QuicHttpStream close itself.
sclittlec4dc1a32015-09-24 00:15:451400 ProcessPacket(ConstructResponseHeadersPacket(2, kFin, nullptr));
[email protected]24e5bc52013-09-18 15:36:581401
fdoray92e35a72016-06-10 15:54:551402 base::RunLoop().RunUntilIdle();
rchb27683c2015-07-29 23:53:501403
[email protected]24e5bc52013-09-18 15:36:581404 EXPECT_TRUE(AtEof());
sclittle1edeeb22015-09-02 20:46:101405
1406 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
sclittlec4dc1a32015-09-24 00:15:451407 // headers and payload.
1408 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
1409 stream_->GetTotalSentBytes());
1410 // Zero since the stream is closed before processing the headers.
sclittle1edeeb22015-09-02 20:46:101411 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]24e5bc52013-09-18 15:36:581412}
1413
[email protected]e1cca9a2013-09-20 17:14:441414// Regression test for http://crbug.com/294870
[email protected]1e960032013-12-20 19:00:201415TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
1416 SetRequest("GET", "/", MEDIUM);
[email protected]e1cca9a2013-09-20 17:14:441417 use_closing_stream_ = true;
[email protected]459a7402014-02-10 12:58:521418
alyssar2adf3ac2016-05-03 17:12:581419 AddWrite(ConstructClientRstStreamPacket(1));
[email protected]459a7402014-02-10 12:58:521420
[email protected]e1cca9a2013-09-20 17:14:441421 Initialize();
1422
1423 request_.method = "GET";
rch9ae5b3b2016-02-11 00:36:291424 request_.url = GURL("http://www.example.org/");
[email protected]e1cca9a2013-09-20 17:14:441425
xunjieli5fafe142016-03-23 23:32:541426 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, net_log_.bound(),
rjshaded5ced072015-12-18 19:26:021427 callback_.callback()));
[email protected]e1cca9a2013-09-20 17:14:441428
1429 // Check that priority is highest.
rch12fef552016-01-15 16:26:311430 QuicChromiumClientStream* reliable_stream =
1431 QuicHttpStreamPeer::GetQuicChromiumClientStream(stream_.get());
[email protected]e1cca9a2013-09-20 17:14:441432 DCHECK(reliable_stream);
rch12fef552016-01-15 16:26:311433 QuicChromiumClientStream::Delegate* delegate = reliable_stream->GetDelegate();
[email protected]e1cca9a2013-09-20 17:14:441434 DCHECK(delegate);
fayanga64c1a92016-02-13 01:55:581435 DCHECK_EQ(kV3HighestPriority, reliable_stream->priority());
[email protected]e1cca9a2013-09-20 17:14:441436
ianswett0888cff2015-11-24 17:42:161437 // Set Delegate to nullptr and make sure Priority returns highest
[email protected]e1cca9a2013-09-20 17:14:441438 // priority.
rtennetibe635732014-10-02 22:51:421439 reliable_stream->SetDelegate(nullptr);
fayanga64c1a92016-02-13 01:55:581440 DCHECK_EQ(kV3HighestPriority, reliable_stream->priority());
[email protected]e1cca9a2013-09-20 17:14:441441 reliable_stream->SetDelegate(delegate);
sclittle1edeeb22015-09-02 20:46:101442
sclittle1edeeb22015-09-02 20:46:101443 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1444 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
[email protected]e1cca9a2013-09-20 17:14:441445}
1446
xunjieli8dff50b2016-07-22 14:19:061447TEST_P(QuicHttpStreamTest, SessionClosedDuringDoLoop) {
1448 SetRequest("POST", "/", DEFAULT_PRIORITY);
1449 size_t spdy_request_headers_frame_length;
1450 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1451 &spdy_request_headers_frame_length));
1452 AddWrite(
1453 ConstructClientDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
1454 // Second data write will result in a synchronous failure which will close
1455 // the session.
1456 AddWrite(SYNCHRONOUS, ERR_FAILED);
1457 Initialize();
1458
1459 ChunkedUploadDataStream upload_data_stream(0);
1460
1461 request_.method = "POST";
1462 request_.url = GURL("http://www.example.org/");
1463 request_.upload_data_stream = &upload_data_stream;
1464 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521465 TestCompletionCallback().callback(), BoundNetLog()));
xunjieli8dff50b2016-07-22 14:19:061466
1467 size_t chunk_size = strlen(kUploadData);
1468 upload_data_stream.AppendData(kUploadData, chunk_size, false);
1469 ASSERT_EQ(OK,
1470 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1471 net_log_.bound(), callback_.callback()));
1472 QuicHttpStream* stream = stream_.get();
1473 DeleteStreamCallback delete_stream_callback(std::move(stream_));
1474 // SendRequest() completes asynchronously after the final chunk is added.
1475 ASSERT_EQ(ERR_IO_PENDING,
1476 stream->SendRequest(headers_, &response_, callback_.callback()));
1477 upload_data_stream.AppendData(kUploadData, chunk_size, true);
1478 int rv = callback_.WaitForResult();
1479 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, rv);
1480}
1481
rtenneti15656ae2016-01-23 03:05:031482TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendHeadersComplete) {
1483 SetRequest("POST", "/", DEFAULT_PRIORITY);
1484 AddWrite(SYNCHRONOUS, ERR_FAILED);
1485 Initialize();
1486
1487 ChunkedUploadDataStream upload_data_stream(0);
1488
1489 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291490 request_.url = GURL("http://www.example.org/");
rtenneti15656ae2016-01-23 03:05:031491 request_.upload_data_stream = &upload_data_stream;
1492 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521493 TestCompletionCallback().callback(), BoundNetLog()));
rtenneti15656ae2016-01-23 03:05:031494
xunjieli5fafe142016-03-23 23:32:541495 ASSERT_EQ(OK,
1496 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1497 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031498 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1499 stream_->SendRequest(headers_, &response_, callback_.callback()));
1500}
1501
1502TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendBodyComplete) {
1503 SetRequest("POST", "/", DEFAULT_PRIORITY);
1504 size_t spdy_request_headers_frame_length;
1505 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1506 &spdy_request_headers_frame_length));
1507 AddWrite(SYNCHRONOUS, ERR_FAILED);
1508 Initialize();
1509
1510 ChunkedUploadDataStream upload_data_stream(0);
1511 size_t chunk_size = strlen(kUploadData);
1512 upload_data_stream.AppendData(kUploadData, chunk_size, false);
1513
1514 request_.method = "POST";
rch9ae5b3b2016-02-11 00:36:291515 request_.url = GURL("http://www.example.org/");
rtenneti15656ae2016-01-23 03:05:031516 request_.upload_data_stream = &upload_data_stream;
1517 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:521518 TestCompletionCallback().callback(), BoundNetLog()));
rtenneti15656ae2016-01-23 03:05:031519
xunjieli5fafe142016-03-23 23:32:541520 ASSERT_EQ(OK,
1521 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1522 net_log_.bound(), callback_.callback()));
rtenneti15656ae2016-01-23 03:05:031523 ASSERT_EQ(ERR_QUIC_PROTOCOL_ERROR,
1524 stream_->SendRequest(headers_, &response_, callback_.callback()));
1525}
1526
ckrasic3865ee0f2016-02-29 22:04:561527TEST_P(QuicHttpStreamTest, ServerPushGetRequest) {
1528 SetRequest("GET", "/", DEFAULT_PRIORITY);
1529 Initialize();
1530
1531 // Initialize the first stream, for receiving the promise on.
1532 request_.method = "GET";
1533 request_.url = GURL("http://www.example.org/");
1534
xunjieli5fafe142016-03-23 23:32:541535 EXPECT_EQ(OK,
1536 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1537 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561538
1539 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1540 // packet, but does it matter?
1541 ReceivePromise(promise_id_);
1542 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1543
1544 request_.url = GURL(promise_url_);
1545
1546 // Make the second stream that will exercise the first step of the
1547 // server push rendezvous mechanism.
xunjieli5fafe142016-03-23 23:32:541548 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1549 net_log_.bound(),
1550 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561551
1552 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251553 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561554 size_t spdy_response_headers_frame_length;
1555 ProcessPacket(InnerConstructResponseHeadersPacket(
1556 1, promise_id_, false, &spdy_response_headers_frame_length));
1557
1558 // Receive the promised response body.
1559 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581560 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1561 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561562
1563 // Now sending a matching request will have successful rendezvous
1564 // with the promised stream.
1565 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1566 callback_.callback()));
1567
1568 EXPECT_EQ(
1569 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1570 ->id(),
1571 promise_id_);
1572
1573 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011574 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1575 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561576
1577 // As will be the body.
1578 EXPECT_EQ(
1579 static_cast<int>(strlen(kResponseBody)),
1580 promised_stream_->ReadResponseBody(
1581 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1582 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1583 EXPECT_TRUE(AtEof());
1584
1585 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1586 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1587 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1588 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1589 strlen(kResponseBody)),
1590 promised_stream_->GetTotalReceivedBytes());
1591}
1592
1593TEST_P(QuicHttpStreamTest, ServerPushGetRequestSlowResponse) {
1594 SetRequest("GET", "/", DEFAULT_PRIORITY);
1595 Initialize();
1596
1597 // Initialize the first stream, for receiving the promise on.
1598 request_.method = "GET";
1599 request_.url = GURL("http://www.example.org/");
1600
xunjieli5fafe142016-03-23 23:32:541601 EXPECT_EQ(OK,
1602 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1603 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561604
1605 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1606 // packet, but does it matter?
1607 ReceivePromise(promise_id_);
1608 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1609
1610 request_.url = GURL(promise_url_);
1611
1612 // Make the second stream that will exercise the first step of the
1613 // server push rendezvous mechanism.
xunjieli5fafe142016-03-23 23:32:541614 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1615 net_log_.bound(),
1616 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561617
1618 // Now sending a matching request will rendezvous with the promised
1619 // stream, but pending secondary validation.
1620 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1621 headers_, &response_, callback_.callback()));
1622
1623 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251624 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561625 size_t spdy_response_headers_frame_length;
1626 ProcessPacket(InnerConstructResponseHeadersPacket(
1627 1, promise_id_, false, &spdy_response_headers_frame_length));
1628
1629 // Receive the promised response body.
1630 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581631 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1632 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561633
fdoray92e35a72016-06-10 15:54:551634 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561635
1636 // Rendezvous should have succeeded now, so the promised stream
1637 // should point at our push stream, and we should be able read
1638 // headers and data from it.
robpercival214763f2016-07-01 23:27:011639 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561640
1641 EXPECT_EQ(
1642 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1643 ->id(),
1644 promise_id_);
1645
robpercival214763f2016-07-01 23:27:011646 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1647 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561648
1649 EXPECT_EQ(
1650 static_cast<int>(strlen(kResponseBody)),
1651 promised_stream_->ReadResponseBody(
1652 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1653
1654 // Callback should return
1655 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1656 EXPECT_TRUE(AtEof());
1657
1658 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1659 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1660 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1661 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1662 strlen(kResponseBody)),
1663 promised_stream_->GetTotalReceivedBytes());
1664}
1665
ckrasic2c63f9b2016-08-16 23:54:071666// Verify fix for crbug.com/637349
1667TEST_P(QuicHttpStreamTest, ServerPushCancelHttpStreamBeforeResponse) {
1668 SetRequest("GET", "/", DEFAULT_PRIORITY);
1669 Initialize();
1670
1671 // Initialize the first stream, for receiving the promise on.
1672 request_.method = "GET";
1673 request_.url = GURL("http://www.example.org/");
1674
1675 EXPECT_EQ(OK,
1676 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1677 net_log_.bound(), callback_.callback()));
1678
1679 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1680 // packet, but does it matter?
1681 ReceivePromise(promise_id_);
1682 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1683
1684 request_.url = GURL(promise_url_);
1685
1686 // Make the second stream that will exercise the first step of the
1687 // server push rendezvous mechanism.
1688 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1689 net_log_.bound(),
1690 callback_.callback()));
1691
1692 // Now sending a matching request will rendezvous with the promised
1693 // stream, but pending secondary validation.
1694 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1695 headers_, &response_, callback_.callback()));
1696
1697 base::RunLoop().RunUntilIdle();
1698
1699 // Cause of FinalValidation() crash as per bug.
1700 promised_stream_.reset();
1701
1702 // Receive the promised response headers.
1703 response_headers_ = promised_response_.Clone();
1704 size_t spdy_response_headers_frame_length;
1705 ProcessPacket(InnerConstructResponseHeadersPacket(
1706 1, promise_id_, false, &spdy_response_headers_frame_length));
1707}
1708
ckrasic3865ee0f2016-02-29 22:04:561709TEST_P(QuicHttpStreamTest, ServerPushCrossOriginOK) {
1710 SetRequest("GET", "/", DEFAULT_PRIORITY);
1711 Initialize();
1712
1713 // Initialize the first stream, for receiving the promise on.
1714 request_.method = "GET";
1715 request_.url = GURL("http://www.example.org/");
1716
xunjieli5fafe142016-03-23 23:32:541717 EXPECT_EQ(OK,
1718 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1719 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561720
1721 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1722 // packet, but does it matter?
1723
1724 push_promise_[":authority"] = "mail.example.org";
1725 promise_url_ = SpdyUtils::GetUrlFromHeaderBlock(push_promise_);
1726 serialized_push_promise_ =
1727 SpdyUtils::SerializeUncompressedHeaders(push_promise_);
1728
1729 ReceivePromise(promise_id_);
1730 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1731
1732 request_.url = GURL(promise_url_);
1733
1734 // Make the second stream that will exercise the first step of the
1735 // server push rendezvous mechanism.
xunjieli5fafe142016-03-23 23:32:541736 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1737 net_log_.bound(),
1738 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561739
1740 // Receive the promised response headers.
bnc94893a72016-06-30 13:45:251741 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561742 size_t spdy_response_headers_frame_length;
1743 ProcessPacket(InnerConstructResponseHeadersPacket(
1744 1, promise_id_, false, &spdy_response_headers_frame_length));
1745
1746 // Receive the promised response body.
1747 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581748 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1749 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561750
1751 // Now sending a matching request will have successful rendezvous
1752 // with the promised stream.
1753 EXPECT_EQ(OK, promised_stream_->SendRequest(headers_, &response_,
1754 callback_.callback()));
1755
1756 EXPECT_EQ(
1757 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1758 ->id(),
1759 promise_id_);
1760
1761 // The headers will be immediately available.
robpercival214763f2016-07-01 23:27:011762 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1763 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561764
1765 // As will be the body.
1766 EXPECT_EQ(
1767 static_cast<int>(strlen(kResponseBody)),
1768 promised_stream_->ReadResponseBody(
1769 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1770 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1771 EXPECT_TRUE(AtEof());
1772
1773 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1774 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1775 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1776 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1777 strlen(kResponseBody)),
1778 promised_stream_->GetTotalReceivedBytes());
1779}
1780
1781TEST_P(QuicHttpStreamTest, ServerPushCrossOriginFail) {
1782 SetRequest("GET", "/", DEFAULT_PRIORITY);
1783 Initialize();
1784
1785 // Initialize the first stream, for receiving the promise on.
1786 request_.method = "GET";
1787 request_.url = GURL("http://www.example.org/");
1788
xunjieli5fafe142016-03-23 23:32:541789 EXPECT_EQ(OK,
1790 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1791 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561792
1793 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1794 // packet, but does it matter?
1795 push_promise_[":authority"] = "www.notexample.org";
1796 promise_url_ = SpdyUtils::GetUrlFromHeaderBlock(push_promise_);
1797 serialized_push_promise_ =
1798 SpdyUtils::SerializeUncompressedHeaders(push_promise_);
1799
1800 ReceivePromise(promise_id_);
1801 // The promise will have been rejected because the cert doesn't
1802 // match.
1803 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
1804}
1805
1806TEST_P(QuicHttpStreamTest, ServerPushVaryCheckOK) {
1807 SetRequest("GET", "/", DEFAULT_PRIORITY);
1808 Initialize();
1809
1810 // Initialize the first stream, for receiving the promise on.
1811 request_.method = "GET";
1812 request_.url = GURL("http://www.example.org/");
1813
xunjieli5fafe142016-03-23 23:32:541814 EXPECT_EQ(OK,
1815 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1816 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561817
1818 push_promise_["accept-encoding"] = "gzip";
1819 serialized_push_promise_ =
1820 SpdyUtils::SerializeUncompressedHeaders(push_promise_);
1821
1822 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1823 // packet, but does it matter?
1824 ReceivePromise(promise_id_);
1825 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1826
1827 request_.url = GURL(promise_url_);
1828
1829 // Make the second stream that will exercise the first step of the
1830 // server push rendezvous mechanism.
xunjieli5fafe142016-03-23 23:32:541831 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1832 net_log_.bound(),
1833 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561834
1835 headers_.SetHeader("accept-encoding", "gzip");
1836
1837 // Now sending a matching request will rendezvous with the promised
1838 // stream, but pending secondary validation.
1839 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1840 headers_, &response_, callback_.callback()));
1841
1842 // Receive the promised response headers.
1843 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:251844 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561845 size_t spdy_response_headers_frame_length;
1846 ProcessPacket(InnerConstructResponseHeadersPacket(
1847 1, promise_id_, false, &spdy_response_headers_frame_length));
1848
1849 // Receive the promised response body.
1850 const char kResponseBody[] = "Hello world!";
alyssar2adf3ac2016-05-03 17:12:581851 ProcessPacket(InnerConstructDataPacket(2, promise_id_, false, kFin, 0,
1852 kResponseBody, &server_maker_));
ckrasic3865ee0f2016-02-29 22:04:561853
fdoray92e35a72016-06-10 15:54:551854 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561855
1856 // Rendezvous should have succeeded now, so the promised stream
1857 // should point at our push stream, and we should be able read
1858 // headers and data from it.
robpercival214763f2016-07-01 23:27:011859 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561860
1861 EXPECT_EQ(
1862 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1863 ->id(),
1864 promise_id_);
1865
robpercival214763f2016-07-01 23:27:011866 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1867 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561868
1869 EXPECT_EQ(
1870 static_cast<int>(strlen(kResponseBody)),
1871 promised_stream_->ReadResponseBody(
1872 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1873
1874 // Callback should return
1875 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1876 EXPECT_TRUE(AtEof());
1877
1878 EXPECT_EQ(0, stream_->GetTotalSentBytes());
1879 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
1880 EXPECT_EQ(0, promised_stream_->GetTotalSentBytes());
1881 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
1882 strlen(kResponseBody)),
1883 promised_stream_->GetTotalReceivedBytes());
1884}
1885
1886TEST_P(QuicHttpStreamTest, ServerPushVaryCheckFail) {
1887 SetRequest("GET", "/", DEFAULT_PRIORITY);
1888 request_headers_[":scheme"] = "https";
1889 request_headers_[":path"] = "/bar";
1890 request_headers_["accept-encoding"] = "sdch";
1891
1892 size_t spdy_request_header_frame_length;
alyssar2adf3ac2016-05-03 17:12:581893 AddWrite(ConstructClientRstStreamVaryMismatchPacket(1));
ckrasic3865ee0f2016-02-29 22:04:561894 AddWrite(InnerConstructRequestHeadersPacket(
1895 2, stream_id_ + 2, !kIncludeVersion, kFin, DEFAULT_PRIORITY,
xunjieli100937eb52016-09-15 20:09:371896 &spdy_request_header_frame_length, /*offset=*/nullptr));
alyssar2adf3ac2016-05-03 17:12:581897 AddWrite(ConstructClientAckPacket(3, 3, 1));
1898 AddWrite(ConstructClientRstStreamCancelledPacket(4));
ckrasic3865ee0f2016-02-29 22:04:561899 Initialize();
1900
1901 // Initialize the first stream, for receiving the promise on.
1902 request_.method = "GET";
1903 request_.url = GURL("http://www.example.org/");
1904
xunjieli5fafe142016-03-23 23:32:541905 EXPECT_EQ(OK,
1906 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1907 net_log_.bound(), callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561908
1909 push_promise_["accept-encoding"] = "gzip";
1910 serialized_push_promise_ =
1911 SpdyUtils::SerializeUncompressedHeaders(push_promise_);
1912
1913 // TODO(ckrasic) - could do this via constructing a PUSH_PROMISE
1914 // packet, but does it matter?
1915 ReceivePromise(promise_id_);
1916 EXPECT_NE(session_->GetPromisedByUrl(promise_url_), nullptr);
1917
1918 request_.url = GURL(promise_url_);
1919
1920 // Make the second stream that will exercise the first step of the
1921 // server push rendezvous mechanism.
xunjieli5fafe142016-03-23 23:32:541922 EXPECT_EQ(OK, promised_stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
1923 net_log_.bound(),
1924 callback_.callback()));
ckrasic3865ee0f2016-02-29 22:04:561925
1926 headers_.SetHeader("accept-encoding", "sdch");
1927
1928 // Now sending a matching request will rendezvous with the promised
1929 // stream, but pending secondary validation.
1930 EXPECT_EQ(ERR_IO_PENDING, promised_stream_->SendRequest(
1931 headers_, &response_, callback_.callback()));
1932
1933 // Receive the promised response headers.
1934 promised_response_["vary"] = "accept-encoding";
bnc94893a72016-06-30 13:45:251935 response_headers_ = promised_response_.Clone();
ckrasic3865ee0f2016-02-29 22:04:561936 size_t spdy_response_headers_frame_length;
1937 ProcessPacket(InnerConstructResponseHeadersPacket(
1938 1, promise_id_, false, &spdy_response_headers_frame_length));
1939
fdoray92e35a72016-06-10 15:54:551940 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561941
1942 // Rendezvous should have failed due to vary mismatch, so the
1943 // promised stream should have been aborted, and instead we have a
1944 // new, regular client initiated stream.
robpercival214763f2016-07-01 23:27:011945 EXPECT_THAT(callback_.WaitForResult(), IsOk());
ckrasic3865ee0f2016-02-29 22:04:561946
1947 // Not a server-initiated stream.
1948 EXPECT_NE(
1949 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1950 ->id(),
1951 promise_id_);
1952
1953 // Instead, a new client-initiated stream.
1954 EXPECT_EQ(
1955 QuicHttpStreamPeer::GetQuicChromiumClientStream(promised_stream_.get())
1956 ->id(),
1957 stream_id_ + 2);
1958
1959 // After rendezvous failure, the push stream has been cancelled.
1960 EXPECT_EQ(session_->GetPromisedByUrl(promise_url_), nullptr);
1961
1962 // The rest of the test verifies that the retried as
1963 // client-initiated version of |promised_stream_| works as intended.
1964
1965 // Ack the request.
alyssar2adf3ac2016-05-03 17:12:581966 ProcessPacket(ConstructServerAckPacket(2, 0, 0));
ckrasic3865ee0f2016-02-29 22:04:561967
bnc614a92d32016-04-04 13:56:071968 SetResponse("404 Not Found", string());
ckrasic3865ee0f2016-02-29 22:04:561969 size_t spdy_response_header_frame_length;
1970 ProcessPacket(InnerConstructResponseHeadersPacket(
1971 3, stream_id_ + 2, kFin, &spdy_response_header_frame_length));
1972
fdoray92e35a72016-06-10 15:54:551973 base::RunLoop().RunUntilIdle();
ckrasic3865ee0f2016-02-29 22:04:561974
robpercival214763f2016-07-01 23:27:011975 EXPECT_THAT(promised_stream_->ReadResponseHeaders(callback_.callback()),
1976 IsOk());
ckrasic3865ee0f2016-02-29 22:04:561977 ASSERT_TRUE(response_.headers.get());
1978 EXPECT_EQ(404, response_.headers->response_code());
1979 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
1980 EXPECT_FALSE(response_.response_time.is_null());
1981 EXPECT_FALSE(response_.request_time.is_null());
1982
1983 // There is no body, so this should return immediately.
1984 EXPECT_EQ(
1985 0, promised_stream_->ReadResponseBody(
1986 read_buffer_.get(), read_buffer_->size(), callback_.callback()));
1987 EXPECT_TRUE(promised_stream_->IsResponseBodyComplete());
1988
1989 stream_->Close(true);
1990
1991 EXPECT_TRUE(AtEof());
1992
1993 // QuicHttpStream::GetTotalSent/ReceivedBytes currently only includes the
1994 // headers and payload.
1995 EXPECT_EQ(static_cast<int64_t>(spdy_request_header_frame_length),
1996 promised_stream_->GetTotalSentBytes());
1997 EXPECT_EQ(static_cast<int64_t>(spdy_response_header_frame_length),
1998 promised_stream_->GetTotalReceivedBytes());
1999}
2000
maksim.sisov84e20c92016-06-23 08:49:342001TEST_P(QuicHttpStreamTest, DataReadErrorSynchronous) {
2002 SetRequest("POST", "/", DEFAULT_PRIORITY);
2003 size_t spdy_request_headers_frame_length;
2004 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
2005 &spdy_request_headers_frame_length));
2006 AddWrite(ConstructClientRstStreamErrorPacket(2, kIncludeVersion));
2007
2008 Initialize();
2009
2010 ReadErrorUploadDataStream upload_data_stream(
2011 ReadErrorUploadDataStream::FailureMode::SYNC);
2012 request_.method = "POST";
2013 request_.url = GURL("http://www.example.org/");
2014 request_.upload_data_stream = &upload_data_stream;
2015 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:522016 TestCompletionCallback().callback(), BoundNetLog()));
maksim.sisov84e20c92016-06-23 08:49:342017
2018 EXPECT_EQ(OK,
2019 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
2020 net_log_.bound(), callback_.callback()));
2021
2022 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
robpercival214763f2016-07-01 23:27:012023 EXPECT_THAT(result, IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342024
2025 EXPECT_TRUE(AtEof());
2026
2027 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2028 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2029 stream_->GetTotalSentBytes());
2030 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2031}
2032
2033TEST_P(QuicHttpStreamTest, DataReadErrorAsynchronous) {
2034 SetRequest("POST", "/", DEFAULT_PRIORITY);
2035 size_t spdy_request_headers_frame_length;
2036 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
2037 &spdy_request_headers_frame_length));
2038 AddWrite(ConstructClientRstStreamErrorPacket(2, !kIncludeVersion));
2039
2040 Initialize();
2041
2042 ReadErrorUploadDataStream upload_data_stream(
2043 ReadErrorUploadDataStream::FailureMode::ASYNC);
2044 request_.method = "POST";
2045 request_.url = GURL("http://www.example.org/");
2046 request_.upload_data_stream = &upload_data_stream;
2047 ASSERT_EQ(OK, request_.upload_data_stream->Init(
maksim.sisov819ba852016-08-17 08:22:522048 TestCompletionCallback().callback(), BoundNetLog()));
maksim.sisov84e20c92016-06-23 08:49:342049
2050 EXPECT_EQ(OK,
2051 stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
2052 net_log_.bound(), callback_.callback()));
2053
2054 int result = stream_->SendRequest(headers_, &response_, callback_.callback());
2055
2056 ProcessPacket(ConstructServerAckPacket(1, 0, 0));
2057 SetResponse("200 OK", string());
2058
robpercival214763f2016-07-01 23:27:012059 EXPECT_THAT(result, IsError(ERR_IO_PENDING));
2060 EXPECT_THAT(callback_.GetResult(result), IsError(ERR_FAILED));
maksim.sisov84e20c92016-06-23 08:49:342061
2062 EXPECT_TRUE(AtEof());
2063
2064 // QuicHttpStream::GetTotalSent/ReceivedBytes includes only headers.
2065 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
2066 stream_->GetTotalSentBytes());
2067 EXPECT_EQ(0, stream_->GetTotalReceivedBytes());
2068}
2069
[email protected]f702d572012-12-04 15:56:202070} // namespace test
[email protected]f702d572012-12-04 15:56:202071} // namespace net