blob: 4f75ba31819b4e559fe1821e3b48085166c9928c [file] [log] [blame]
xunjieli2608f9b2016-03-14 13:39:231// Copyright 2016 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/quic/bidirectional_stream_quic_impl.h"
6
7#include <stdint.h>
danakjad1777e2016-04-16 00:56:428
9#include <memory>
xunjieli2608f9b2016-03-14 13:39:2310#include <vector>
11
12#include "base/callback_helpers.h"
danakjad1777e2016-04-16 00:56:4213#include "base/memory/ptr_util.h"
xunjieli2608f9b2016-03-14 13:39:2314#include "base/message_loop/message_loop.h"
15#include "base/run_loop.h"
16#include "base/strings/string_number_conversions.h"
martijna4804402016-03-29 08:24:2717#include "net/base/ip_address.h"
xunjieli2608f9b2016-03-14 13:39:2318#include "net/base/net_errors.h"
19#include "net/http/bidirectional_stream_request_info.h"
20#include "net/http/transport_security_state.h"
xunjieli5fafe142016-03-23 23:32:5421#include "net/log/test_net_log.h"
22#include "net/log/test_net_log_util.h"
xunjieli2608f9b2016-03-14 13:39:2323#include "net/quic/crypto/crypto_protocol.h"
24#include "net/quic/crypto/quic_decrypter.h"
25#include "net/quic/crypto/quic_encrypter.h"
26#include "net/quic/crypto/quic_server_info.h"
rch16c74d1d2016-04-22 06:14:0727#include "net/quic/quic_chromium_alarm_factory.h"
xunjieli2608f9b2016-03-14 13:39:2328#include "net/quic/quic_chromium_client_session.h"
29#include "net/quic/quic_chromium_client_stream.h"
30#include "net/quic/quic_chromium_connection_helper.h"
31#include "net/quic/quic_chromium_packet_reader.h"
32#include "net/quic/quic_chromium_packet_writer.h"
33#include "net/quic/quic_connection.h"
34#include "net/quic/quic_http_utils.h"
35#include "net/quic/spdy_utils.h"
36#include "net/quic/test_tools/crypto_test_utils.h"
37#include "net/quic/test_tools/mock_clock.h"
38#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
39#include "net/quic/test_tools/mock_random.h"
40#include "net/quic/test_tools/quic_connection_peer.h"
41#include "net/quic/test_tools/quic_test_packet_maker.h"
42#include "net/quic/test_tools/quic_test_utils.h"
43#include "net/quic/test_tools/test_task_runner.h"
44#include "net/socket/socket_test_util.h"
45#include "testing/gmock/include/gmock/gmock.h"
46#include "testing/gtest/include/gtest/gtest.h"
47
48namespace net {
49
50namespace test {
51
52namespace {
53
54const char kUploadData[] = "Really nifty data!";
55const char kDefaultServerHostName[] = "www.google.com";
56const uint16_t kDefaultServerPort = 80;
57// Size of the buffer to be allocated for each read.
58const size_t kReadBufferSize = 4096;
59
xunjieli5749218c2016-03-22 16:43:0660class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
xunjieli2608f9b2016-03-14 13:39:2361 public:
62 TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
63 : TestDelegateBase(read_buf,
64 read_buf_len,
danakjad1777e2016-04-16 00:56:4265 base::WrapUnique(new base::Timer(false, false))) {}
xunjieli2608f9b2016-03-14 13:39:2366
67 TestDelegateBase(IOBuffer* read_buf,
68 int read_buf_len,
danakjad1777e2016-04-16 00:56:4269 std::unique_ptr<base::Timer> timer)
xunjieli2608f9b2016-03-14 13:39:2370 : read_buf_(read_buf),
71 read_buf_len_(read_buf_len),
72 timer_(std::move(timer)),
73 loop_(nullptr),
74 error_(OK),
75 on_data_read_count_(0),
76 on_data_sent_count_(0),
77 not_expect_callback_(false) {
78 loop_.reset(new base::RunLoop);
79 }
80
81 ~TestDelegateBase() override {}
82
83 void OnHeadersSent() override {
84 CHECK(!not_expect_callback_);
85 loop_->Quit();
86 }
87
88 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
89 CHECK(!not_expect_callback_);
90
91 response_headers_ = response_headers;
92 loop_->Quit();
93 }
94
95 void OnDataRead(int bytes_read) override {
96 CHECK(!not_expect_callback_);
97 CHECK(!callback_.is_null());
98
99 ++on_data_read_count_;
100 CHECK_GE(bytes_read, OK);
101 data_received_.append(read_buf_->data(), bytes_read);
102 base::ResetAndReturn(&callback_).Run(bytes_read);
103 }
104
105 void OnDataSent() override {
106 CHECK(!not_expect_callback_);
107
108 ++on_data_sent_count_;
109 loop_->Quit();
110 }
111
112 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
113 CHECK(!not_expect_callback_);
114
115 trailers_ = trailers;
116 loop_->Quit();
117 }
118
119 void OnFailed(int error) override {
120 CHECK(!not_expect_callback_);
121 CHECK_EQ(OK, error_);
122 CHECK_NE(OK, error);
123
124 error_ = error;
125 loop_->Quit();
126 }
127
128 void Start(const BidirectionalStreamRequestInfo* request_info,
129 const BoundNetLog& net_log,
130 const base::WeakPtr<QuicChromiumClientSession> session) {
131 stream_job_.reset(new BidirectionalStreamQuicImpl(session));
132 stream_job_->Start(request_info, net_log, this, nullptr);
133 }
134
135 void SendData(IOBuffer* data, int length, bool end_of_stream) {
136 not_expect_callback_ = true;
137 stream_job_->SendData(data, length, end_of_stream);
138 not_expect_callback_ = false;
139 }
140
141 // Waits until next Delegate callback.
142 void WaitUntilNextCallback() {
143 loop_->Run();
144 loop_.reset(new base::RunLoop);
145 }
146
147 // Calls ReadData on the |stream_| and updates |data_received_|.
148 int ReadData(const CompletionCallback& callback) {
149 not_expect_callback_ = true;
150 int rv = stream_job_->ReadData(read_buf_.get(), read_buf_len_);
151 not_expect_callback_ = false;
152 if (rv > 0)
153 data_received_.append(read_buf_->data(), rv);
154 if (rv == ERR_IO_PENDING)
155 callback_ = callback;
156 return rv;
157 }
158
159 // Cancels |stream_|.
160 void CancelStream() { stream_job_->Cancel(); }
161
162 NextProto GetProtocol() const { return stream_job_->GetProtocol(); }
163
164 int64_t GetTotalReceivedBytes() const {
165 return stream_job_->GetTotalReceivedBytes();
166 }
167
168 int64_t GetTotalSentBytes() const { return stream_job_->GetTotalSentBytes(); }
169
170 // Const getters for internal states.
171 const std::string& data_received() const { return data_received_; }
172 int error() const { return error_; }
173 const SpdyHeaderBlock& response_headers() const { return response_headers_; }
174 const SpdyHeaderBlock& trailers() const { return trailers_; }
175 int on_data_read_count() const { return on_data_read_count_; }
176 int on_data_sent_count() const { return on_data_sent_count_; }
177
178 protected:
179 // Quits |loop_|.
180 void QuitLoop() { loop_->Quit(); }
181
182 // Deletes |stream_|.
183 void DeleteStream() { stream_job_.reset(); }
184
185 private:
danakjad1777e2016-04-16 00:56:42186 std::unique_ptr<BidirectionalStreamQuicImpl> stream_job_;
xunjieli2608f9b2016-03-14 13:39:23187 scoped_refptr<IOBuffer> read_buf_;
188 int read_buf_len_;
danakjad1777e2016-04-16 00:56:42189 std::unique_ptr<base::Timer> timer_;
xunjieli2608f9b2016-03-14 13:39:23190 std::string data_received_;
danakjad1777e2016-04-16 00:56:42191 std::unique_ptr<base::RunLoop> loop_;
xunjieli2608f9b2016-03-14 13:39:23192 SpdyHeaderBlock response_headers_;
193 SpdyHeaderBlock trailers_;
194 int error_;
195 int on_data_read_count_;
196 int on_data_sent_count_;
197 // This is to ensure that delegate callback is not invoked synchronously when
198 // calling into |stream_|.
199 bool not_expect_callback_;
200 CompletionCallback callback_;
201
202 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase);
203};
204
205// A delegate that deletes the stream in a particular callback.
206class DeleteStreamDelegate : public TestDelegateBase {
207 public:
208 // Specifies in which callback the stream can be deleted.
209 enum Phase {
210 ON_HEADERS_RECEIVED,
211 ON_DATA_READ,
212 ON_TRAILERS_RECEIVED,
213 ON_FAILED,
214 };
215
216 DeleteStreamDelegate(IOBuffer* buf, int buf_len, Phase phase, bool do_cancel)
217 : TestDelegateBase(buf, buf_len), phase_(phase), do_cancel_(do_cancel) {}
218 ~DeleteStreamDelegate() override {}
219
220 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
221 if (phase_ == ON_HEADERS_RECEIVED) {
222 DeleteStream();
223 }
224 TestDelegateBase::OnHeadersReceived(response_headers);
225 }
226
227 void OnDataSent() override { NOTREACHED(); }
228
229 void OnDataRead(int bytes_read) override {
230 DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
231 if (phase_ == ON_DATA_READ)
232 DeleteStream();
233 TestDelegateBase::OnDataRead(bytes_read);
234 }
235
236 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
237 DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
238 DCHECK_NE(ON_DATA_READ, phase_);
239 if (phase_ == ON_TRAILERS_RECEIVED)
240 DeleteStream();
241 TestDelegateBase::OnTrailersReceived(trailers);
242 }
243
244 void OnFailed(int error) override {
245 DCHECK_EQ(ON_FAILED, phase_);
246 DeleteStream();
247 TestDelegateBase::OnFailed(error);
248 }
249
250 private:
251 // Indicates in which callback the delegate should cancel or delete the
252 // stream.
253 Phase phase_;
254 // Indicates whether to cancel or delete the stream.
255 bool do_cancel_;
256
257 DISALLOW_COPY_AND_ASSIGN(DeleteStreamDelegate);
258};
259
260} // namespace
261
262class BidirectionalStreamQuicImplTest
263 : public ::testing::TestWithParam<QuicVersion> {
264 protected:
265 static const bool kFin = true;
266 static const bool kIncludeVersion = true;
267 static const bool kIncludeCongestionFeedback = true;
268
269 // Holds a packet to be written to the wire, and the IO mode that should
270 // be used by the mock socket when performing the write.
271 struct PacketToWrite {
jokulikf2bd55c52016-03-24 22:35:30272 PacketToWrite(IoMode mode, QuicReceivedPacket* packet)
xunjieli2608f9b2016-03-14 13:39:23273 : mode(mode), packet(packet) {}
274 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
275 IoMode mode;
jokulikf2bd55c52016-03-24 22:35:30276 QuicReceivedPacket* packet;
xunjieli2608f9b2016-03-14 13:39:23277 int rv;
278 };
279
280 BidirectionalStreamQuicImplTest()
xunjieli5fafe142016-03-23 23:32:54281 : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
xunjieli2608f9b2016-03-14 13:39:23282 read_buffer_(new IOBufferWithSize(4096)),
283 connection_id_(2),
284 stream_id_(kClientDataStreamId1),
285 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
286 random_generator_(0) {
martijna4804402016-03-29 08:24:27287 IPAddress ip(192, 0, 2, 33);
xunjieli2608f9b2016-03-14 13:39:23288 peer_addr_ = IPEndPoint(ip, 443);
289 self_addr_ = IPEndPoint(ip, 8435);
290 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
291 }
292
293 ~BidirectionalStreamQuicImplTest() {
294 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
295 for (size_t i = 0; i < writes_.size(); i++) {
296 delete writes_[i].packet;
297 }
298 }
299
300 void TearDown() override {
301 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
302 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
303 }
304
305 // Adds a packet to the list of expected writes.
danakjad1777e2016-04-16 00:56:42306 void AddWrite(std::unique_ptr<QuicReceivedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23307 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
308 }
309
danakjad1777e2016-04-16 00:56:42310 void ProcessPacket(std::unique_ptr<QuicReceivedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23311 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
312 }
313
314 // Configures the test fixture to use the list of expected writes.
315 void Initialize() {
316 mock_writes_.reset(new MockWrite[writes_.size()]);
317 for (size_t i = 0; i < writes_.size(); i++) {
318 if (writes_[i].packet == nullptr) {
319 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
320 } else {
321 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
322 writes_[i].packet->length());
323 }
324 };
325
326 socket_data_.reset(new StaticSocketDataProvider(
327 nullptr, 0, mock_writes_.get(), writes_.size()));
328
danakjad1777e2016-04-16 00:56:42329 std::unique_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
xunjielib53b38c2016-03-24 15:54:36330 socket_data_.get(), net_log().bound().net_log()));
xunjieli2608f9b2016-03-14 13:39:23331 socket->Connect(peer_addr_);
332 runner_ = new TestTaskRunner(&clock_);
rch16c74d1d2016-04-22 06:14:07333 helper_.reset(
334 new QuicChromiumConnectionHelper(&clock_, &random_generator_));
335 alarm_factory_.reset(new QuicChromiumAlarmFactory(runner_.get(), &clock_));
xunjieli2608f9b2016-03-14 13:39:23336 connection_ = new QuicConnection(
rch16c74d1d2016-04-22 06:14:07337 connection_id_, peer_addr_, helper_.get(), alarm_factory_.get(),
xunjielib53b38c2016-03-24 15:54:36338 new QuicChromiumPacketWriter(socket.get()), true /* owns_writer */,
xunjieli2608f9b2016-03-14 13:39:23339 Perspective::IS_CLIENT, SupportedVersions(GetParam()));
340
341 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36342 connection_, std::move(socket),
xunjieli2608f9b2016-03-14 13:39:23343 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
danakjad1777e2016-04-16 00:56:42344 &transport_security_state_, base::WrapUnique((QuicServerInfo*)nullptr),
xunjieli2608f9b2016-03-14 13:39:23345 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
346 PRIVACY_MODE_DISABLED),
347 kQuicYieldAfterPacketsRead,
348 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
349 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
350 "CONNECTION_UNKNOWN", base::TimeTicks::Now(), &push_promise_index_,
351 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54352 /*socket_performance_watcher=*/nullptr, net_log().bound().net_log()));
xunjieli2608f9b2016-03-14 13:39:23353 session_->Initialize();
354 session_->GetCryptoStream()->CryptoConnect();
355 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
356 }
357
358 void SetRequest(const std::string& method,
359 const std::string& path,
360 RequestPriority priority) {
361 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
362 }
363
364 SpdyHeaderBlock ConstructResponseHeaders(const std::string& response_code) {
365 return maker_.GetResponseHeaders(response_code);
366 }
367
danakjad1777e2016-04-16 00:56:42368 std::unique_ptr<QuicReceivedPacket> ConstructDataPacket(
xunjieli2608f9b2016-03-14 13:39:23369 QuicPacketNumber packet_number,
370 bool should_include_version,
371 bool fin,
372 QuicStreamOffset offset,
373 base::StringPiece data) {
danakjad1777e2016-04-16 00:56:42374 std::unique_ptr<QuicReceivedPacket> packet(maker_.MakeDataPacket(
xunjieli2608f9b2016-03-14 13:39:23375 packet_number, stream_id_, should_include_version, fin, offset, data));
376 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
377 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
378 return packet;
379 }
380
danakjad1777e2016-04-16 00:56:42381 std::unique_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
xunjieli2608f9b2016-03-14 13:39:23382 QuicPacketNumber packet_number,
383 bool fin,
384 RequestPriority request_priority,
385 size_t* spdy_headers_frame_length) {
386 SpdyPriority priority =
387 ConvertRequestPriorityToQuicPriority(request_priority);
388 return maker_.MakeRequestHeadersPacket(
389 packet_number, stream_id_, kIncludeVersion, fin, priority,
390 request_headers_, spdy_headers_frame_length);
391 }
392
danakjad1777e2016-04-16 00:56:42393 std::unique_ptr<QuicReceivedPacket> ConstructResponseHeadersPacket(
xunjieli2608f9b2016-03-14 13:39:23394 QuicPacketNumber packet_number,
395 bool fin,
396 const SpdyHeaderBlock& response_headers,
397 size_t* spdy_headers_frame_length,
398 QuicStreamOffset* offset) {
399 return maker_.MakeResponseHeadersPacket(
400 packet_number, stream_id_, !kIncludeVersion, fin, response_headers,
401 spdy_headers_frame_length, offset);
402 }
403
danakjad1777e2016-04-16 00:56:42404 std::unique_ptr<QuicReceivedPacket> ConstructResponseTrailersPacket(
xunjieli2608f9b2016-03-14 13:39:23405 QuicPacketNumber packet_number,
406 bool fin,
407 const SpdyHeaderBlock& trailers,
408 size_t* spdy_headers_frame_length,
409 QuicStreamOffset* offset) {
410 return maker_.MakeResponseHeadersPacket(packet_number, stream_id_,
411 !kIncludeVersion, fin, trailers,
412 spdy_headers_frame_length, offset);
413 }
414
danakjad1777e2016-04-16 00:56:42415 std::unique_ptr<QuicReceivedPacket> ConstructRstStreamPacket(
xunjieli2608f9b2016-03-14 13:39:23416 QuicPacketNumber packet_number) {
417 return ConstructRstStreamCancelledPacket(packet_number, 0);
418 }
419
danakjad1777e2016-04-16 00:56:42420 std::unique_ptr<QuicReceivedPacket> ConstructRstStreamCancelledPacket(
xunjieli2608f9b2016-03-14 13:39:23421 QuicPacketNumber packet_number,
422 size_t bytes_written) {
danakjad1777e2016-04-16 00:56:42423 std::unique_ptr<QuicReceivedPacket> packet(
xunjieli2608f9b2016-03-14 13:39:23424 maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
425 QUIC_STREAM_CANCELLED, bytes_written));
426 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
427 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
428 return packet;
429 }
430
danakjad1777e2016-04-16 00:56:42431 std::unique_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
xunjieli2608f9b2016-03-14 13:39:23432 QuicPacketNumber packet_number,
433 QuicPacketNumber largest_received,
434 QuicPacketNumber ack_least_unacked,
435 QuicPacketNumber stop_least_unacked) {
436 return maker_.MakeAckAndRstPacket(
437 packet_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
438 largest_received, ack_least_unacked, stop_least_unacked,
439 !kIncludeCongestionFeedback);
440 }
441
danakjad1777e2016-04-16 00:56:42442 std::unique_ptr<QuicReceivedPacket> ConstructAckAndDataPacket(
xunjieli2608f9b2016-03-14 13:39:23443 QuicPacketNumber packet_number,
444 bool should_include_version,
445 QuicPacketNumber largest_received,
446 QuicPacketNumber least_unacked,
447 bool fin,
448 QuicStreamOffset offset,
449 base::StringPiece data) {
danakjad1777e2016-04-16 00:56:42450 std::unique_ptr<QuicReceivedPacket> packet(maker_.MakeAckAndDataPacket(
xunjieli2608f9b2016-03-14 13:39:23451 packet_number, should_include_version, stream_id_, largest_received,
452 least_unacked, fin, offset, data));
453 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
454 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
455 return packet;
456 }
457
danakjad1777e2016-04-16 00:56:42458 std::unique_ptr<QuicReceivedPacket> ConstructAckPacket(
xunjieli2608f9b2016-03-14 13:39:23459 QuicPacketNumber packet_number,
460 QuicPacketNumber largest_received,
461 QuicPacketNumber least_unacked) {
462 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
463 !kIncludeCongestionFeedback);
464 }
465
xunjieli5fafe142016-03-23 23:32:54466 const BoundTestNetLog& net_log() const { return net_log_; }
xunjieli2608f9b2016-03-14 13:39:23467
468 QuicChromiumClientSession* session() const { return session_.get(); }
469
470 private:
xunjieli5fafe142016-03-23 23:32:54471 BoundTestNetLog net_log_;
xunjieli2608f9b2016-03-14 13:39:23472 scoped_refptr<TestTaskRunner> runner_;
danakjad1777e2016-04-16 00:56:42473 std::unique_ptr<MockWrite[]> mock_writes_;
xunjieli2608f9b2016-03-14 13:39:23474 MockClock clock_;
475 QuicConnection* connection_;
danakjad1777e2016-04-16 00:56:42476 std::unique_ptr<QuicChromiumConnectionHelper> helper_;
rch16c74d1d2016-04-22 06:14:07477 std::unique_ptr<QuicChromiumAlarmFactory> alarm_factory_;
xunjieli2608f9b2016-03-14 13:39:23478 TransportSecurityState transport_security_state_;
danakjad1777e2016-04-16 00:56:42479 std::unique_ptr<QuicChromiumClientSession> session_;
xunjieli2608f9b2016-03-14 13:39:23480 QuicCryptoClientConfig crypto_config_;
481 HttpRequestHeaders headers_;
482 HttpResponseInfo response_;
483 scoped_refptr<IOBufferWithSize> read_buffer_;
484 SpdyHeaderBlock request_headers_;
485 const QuicConnectionId connection_id_;
486 const QuicStreamId stream_id_;
487 QuicTestPacketMaker maker_;
488 IPEndPoint self_addr_;
489 IPEndPoint peer_addr_;
490 MockRandom random_generator_;
491 MockCryptoClientStreamFactory crypto_client_stream_factory_;
danakjad1777e2016-04-16 00:56:42492 std::unique_ptr<StaticSocketDataProvider> socket_data_;
xunjieli2608f9b2016-03-14 13:39:23493 std::vector<PacketToWrite> writes_;
494 QuicClientPushPromiseIndex push_promise_index_;
495};
496
497INSTANTIATE_TEST_CASE_P(Version,
498 BidirectionalStreamQuicImplTest,
499 ::testing::ValuesIn(QuicSupportedVersions()));
500
501TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
502 SetRequest("GET", "/", DEFAULT_PRIORITY);
503 size_t spdy_request_headers_frame_length;
504 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
505 &spdy_request_headers_frame_length));
506
507 AddWrite(ConstructAckPacket(2, 3, 1));
508 Initialize();
509
510 BidirectionalStreamRequestInfo request;
511 request.method = "GET";
512 request.url = GURL("http://www.google.com/");
513 request.end_stream_on_headers = true;
514 request.priority = DEFAULT_PRIORITY;
515
516 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42517 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23518 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54519 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23520 delegate->WaitUntilNextCallback(); // OnHeadersSent
521
522 // Server acks the request.
523 ProcessPacket(ConstructAckPacket(1, 0, 0));
524
525 // Server sends the response headers.
526 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
527
528 size_t spdy_response_headers_frame_length;
529 QuicStreamOffset offset = 0;
530 ProcessPacket(ConstructResponseHeadersPacket(
531 2, !kFin, response_headers, &spdy_response_headers_frame_length,
532 &offset));
533
534 delegate->WaitUntilNextCallback(); // OnHeadersReceived
535 TestCompletionCallback cb;
536 int rv = delegate->ReadData(cb.callback());
537 EXPECT_EQ(ERR_IO_PENDING, rv);
538 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
539 const char kResponseBody[] = "Hello world!";
540 // Server sends data.
541 ProcessPacket(
542 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
543 EXPECT_EQ(12, cb.WaitForResult());
544
545 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
546 TestCompletionCallback cb2;
547 EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb2.callback()));
548
549 SpdyHeaderBlock trailers;
550 size_t spdy_trailers_frame_length;
551 trailers["foo"] = "bar";
552 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
553 // Server sends trailers.
554 ProcessPacket(ConstructResponseTrailersPacket(
555 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
556
557 delegate->WaitUntilNextCallback(); // OnTrailersReceived
558 EXPECT_EQ(OK, cb2.WaitForResult());
559 trailers.erase(kFinalOffsetHeaderKey);
560 EXPECT_EQ(trailers, delegate->trailers());
561
562 EXPECT_EQ(OK, delegate->ReadData(cb2.callback()));
563 base::MessageLoop::current()->RunUntilIdle();
564
565 EXPECT_EQ(2, delegate->on_data_read_count());
566 EXPECT_EQ(0, delegate->on_data_sent_count());
567 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
568 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
569 delegate->GetTotalSentBytes());
570 EXPECT_EQ(
571 static_cast<int64_t>(spdy_response_headers_frame_length +
572 strlen(kResponseBody) + spdy_trailers_frame_length),
573 delegate->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54574 // Check that NetLog was filled as expected.
575 TestNetLogEntry::List entries;
576 net_log().GetEntries(&entries);
577 size_t pos = ExpectLogContainsSomewhere(
578 entries, /*min_offset=*/0,
579 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
580 NetLog::PHASE_NONE);
581 pos = ExpectLogContainsSomewhere(
582 entries, /*min_offset=*/pos,
583 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
584 NetLog::PHASE_NONE);
585 ExpectLogContainsSomewhere(
586 entries, /*min_offset=*/pos,
587 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
588 NetLog::PHASE_NONE);
xunjieli2608f9b2016-03-14 13:39:23589}
590
591TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
592 SetRequest("POST", "/", DEFAULT_PRIORITY);
593 size_t spdy_request_headers_frame_length;
594 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
595 &spdy_request_headers_frame_length));
596 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
597 AddWrite(ConstructAckPacket(3, 3, 1));
598
599 Initialize();
600
601 BidirectionalStreamRequestInfo request;
602 request.method = "POST";
603 request.url = GURL("http://www.google.com/");
604 request.end_stream_on_headers = false;
605 request.priority = DEFAULT_PRIORITY;
606
607 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42608 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23609 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54610 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23611 delegate->WaitUntilNextCallback(); // OnHeadersSent
612
613 // Send a DATA frame.
614 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
615
616 delegate->SendData(buf.get(), buf->size(), true);
617 delegate->WaitUntilNextCallback(); // OnDataSent
618
619 // Server acks the request.
620 ProcessPacket(ConstructAckPacket(1, 0, 0));
621
622 // Server sends the response headers.
623 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
624 size_t spdy_response_headers_frame_length;
625 QuicStreamOffset offset = 0;
626 ProcessPacket(ConstructResponseHeadersPacket(
627 2, !kFin, response_headers, &spdy_response_headers_frame_length,
628 &offset));
629
630 delegate->WaitUntilNextCallback(); // OnHeadersReceived
631 TestCompletionCallback cb;
632 int rv = delegate->ReadData(cb.callback());
633 EXPECT_EQ(ERR_IO_PENDING, rv);
634 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
635 const char kResponseBody[] = "Hello world!";
636 // Server sends data.
637 ProcessPacket(
638 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
639
640 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult());
641
642 size_t spdy_trailers_frame_length;
643 SpdyHeaderBlock trailers;
644 trailers["foo"] = "bar";
645 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
646 // Server sends trailers.
647 ProcessPacket(ConstructResponseTrailersPacket(
648 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
649
650 delegate->WaitUntilNextCallback(); // OnTrailersReceived
651 trailers.erase(kFinalOffsetHeaderKey);
652 EXPECT_EQ(trailers, delegate->trailers());
653 EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
654
655 EXPECT_EQ(1, delegate->on_data_read_count());
656 EXPECT_EQ(1, delegate->on_data_sent_count());
657 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
658 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
659 strlen(kUploadData)),
660 delegate->GetTotalSentBytes());
661 EXPECT_EQ(
662 static_cast<int64_t>(spdy_response_headers_frame_length +
663 strlen(kResponseBody) + spdy_trailers_frame_length),
664 delegate->GetTotalReceivedBytes());
665}
666
667TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
668 SetRequest("POST", "/", DEFAULT_PRIORITY);
669 size_t spdy_request_headers_frame_length;
670 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
671 &spdy_request_headers_frame_length));
672 AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
673 kUploadData));
674 AddWrite(ConstructAckAndDataPacket(3, !kIncludeVersion, 3, 3, kFin,
675 strlen(kUploadData), kUploadData));
676 Initialize();
677
678 BidirectionalStreamRequestInfo request;
679 request.method = "POST";
680 request.url = GURL("http://www.google.com/");
681 request.end_stream_on_headers = false;
682 request.priority = DEFAULT_PRIORITY;
683
684 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42685 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23686 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54687 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23688 delegate->WaitUntilNextCallback(); // OnHeadersSent
689
690 // Server acks the request.
691 ProcessPacket(ConstructAckPacket(1, 0, 0));
692
693 // Server sends the response headers.
694 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
695 size_t spdy_response_headers_frame_length;
696 ProcessPacket(ConstructResponseHeadersPacket(
697 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
698
699 delegate->WaitUntilNextCallback(); // OnHeadersReceived
700 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
701
702 // Client sends a data packet.
703 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
704
705 delegate->SendData(buf.get(), buf->size(), false);
706 delegate->WaitUntilNextCallback(); // OnDataSent
707
708 TestCompletionCallback cb;
709 int rv = delegate->ReadData(cb.callback());
710 EXPECT_EQ(ERR_IO_PENDING, rv);
711 const char kResponseBody[] = "Hello world!";
712
713 // Server sends a data packet.
714 ProcessPacket(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, !kFin, 0,
715 kResponseBody));
716
717 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
718 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
719
720 // Client sends a data packet.
721 delegate->SendData(buf.get(), buf->size(), true);
722 delegate->WaitUntilNextCallback(); // OnDataSent
723
724 TestCompletionCallback cb2;
725 rv = delegate->ReadData(cb2.callback());
726 EXPECT_EQ(ERR_IO_PENDING, rv);
727 ProcessPacket(ConstructAckAndDataPacket(
728 4, !kIncludeVersion, 3, 1, kFin, strlen(kResponseBody), kResponseBody));
729
730 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb2.WaitForResult());
731
732 std::string expected_body(kResponseBody);
733 expected_body.append(kResponseBody);
734 EXPECT_EQ(expected_body, delegate->data_received());
735
736 EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
737 EXPECT_EQ(2, delegate->on_data_read_count());
738 EXPECT_EQ(2, delegate->on_data_sent_count());
739 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
740 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
741 2 * strlen(kUploadData)),
742 delegate->GetTotalSentBytes());
743 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
744 2 * strlen(kResponseBody)),
745 delegate->GetTotalReceivedBytes());
746}
747
748TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
749 SetRequest("GET", "/", DEFAULT_PRIORITY);
750 size_t spdy_request_headers_frame_length;
751 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
752 &spdy_request_headers_frame_length));
753 Initialize();
754
755 BidirectionalStreamRequestInfo request;
756 request.method = "GET";
757 request.url = GURL("http://www.google.com/");
758 request.end_stream_on_headers = true;
759 request.priority = DEFAULT_PRIORITY;
760
761 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42762 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23763 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54764 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23765 delegate->WaitUntilNextCallback(); // OnHeadersSent
766
767 // Server sends a Rst.
768 ProcessPacket(ConstructRstStreamPacket(1));
769
770 delegate->WaitUntilNextCallback(); // OnFailed
771 TestCompletionCallback cb;
772 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
773
774 base::MessageLoop::current()->RunUntilIdle();
775
776 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
777 EXPECT_EQ(0, delegate->on_data_read_count());
778 EXPECT_EQ(0, delegate->on_data_sent_count());
779 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
780 delegate->GetTotalSentBytes());
781 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
782}
783
784TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
785 SetRequest("GET", "/", DEFAULT_PRIORITY);
786 size_t spdy_request_headers_frame_length;
787 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
788 &spdy_request_headers_frame_length));
789 // Why does QUIC ack Rst? Is this expected?
790 AddWrite(ConstructAckPacket(2, 3, 1));
791
792 Initialize();
793
794 BidirectionalStreamRequestInfo request;
795 request.method = "GET";
796 request.url = GURL("http://www.google.com/");
797 request.end_stream_on_headers = true;
798 request.priority = DEFAULT_PRIORITY;
799
800 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42801 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23802 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54803 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23804 delegate->WaitUntilNextCallback(); // OnHeadersSent
805
806 // Server acks the request.
807 ProcessPacket(ConstructAckPacket(1, 0, 0));
808
809 // Server sends the response headers.
810 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
811
812 size_t spdy_response_headers_frame_length;
813 QuicStreamOffset offset = 0;
814 ProcessPacket(ConstructResponseHeadersPacket(
815 2, !kFin, response_headers, &spdy_response_headers_frame_length,
816 &offset));
817
818 delegate->WaitUntilNextCallback(); // OnHeadersReceived
819 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
820
821 TestCompletionCallback cb;
822 int rv = delegate->ReadData(cb.callback());
823 EXPECT_EQ(ERR_IO_PENDING, rv);
824
825 // Server sends a Rst.
826 ProcessPacket(ConstructRstStreamPacket(3));
827
828 delegate->WaitUntilNextCallback(); // OnFailed
829
830 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
831 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
832 EXPECT_EQ(0, delegate->on_data_read_count());
833 EXPECT_EQ(0, delegate->on_data_sent_count());
834 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
835 delegate->GetTotalSentBytes());
836 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
837 delegate->GetTotalReceivedBytes());
838}
839
840TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterSendData) {
841 SetRequest("POST", "/", DEFAULT_PRIORITY);
842 size_t spdy_request_headers_frame_length;
843 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
844 &spdy_request_headers_frame_length));
845 AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
846 kUploadData));
847 AddWrite(ConstructRstStreamCancelledPacket(3, strlen(kUploadData)));
848
849 Initialize();
850
851 BidirectionalStreamRequestInfo request;
852 request.method = "POST";
853 request.url = GURL("http://www.google.com/");
854 request.end_stream_on_headers = false;
855 request.priority = DEFAULT_PRIORITY;
856
857 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42858 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23859 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54860 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23861 delegate->WaitUntilNextCallback(); // OnHeadersSent
862
863 // Server acks the request.
864 ProcessPacket(ConstructAckPacket(1, 0, 0));
865
866 // Server sends the response headers.
867 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
868 size_t spdy_response_headers_frame_length;
869 ProcessPacket(ConstructResponseHeadersPacket(
870 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
871
872 delegate->WaitUntilNextCallback(); // OnHeadersReceived
873 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
874
875 // Send a DATA frame.
876 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
877
878 delegate->SendData(buf.get(), buf->size(), false);
879 delegate->WaitUntilNextCallback(); // OnDataSent
880
881 delegate->CancelStream();
882 base::MessageLoop::current()->RunUntilIdle();
883
884 EXPECT_EQ(0, delegate->on_data_read_count());
885 EXPECT_EQ(1, delegate->on_data_sent_count());
886 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
887 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
888 strlen(kUploadData)),
889 delegate->GetTotalSentBytes());
890 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
891 delegate->GetTotalReceivedBytes());
892}
893
894TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
895 SetRequest("GET", "/", DEFAULT_PRIORITY);
896 size_t spdy_request_headers_frame_length;
897 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
898 &spdy_request_headers_frame_length));
899 Initialize();
900
901 BidirectionalStreamRequestInfo request;
902 request.method = "GET";
903 request.url = GURL("http://www.google.com/");
904 request.end_stream_on_headers = true;
905 request.priority = DEFAULT_PRIORITY;
906
907 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42908 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23909 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54910 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23911 delegate->WaitUntilNextCallback(); // OnHeadersSent
912
913 // Server acks the request.
914 ProcessPacket(ConstructAckPacket(1, 0, 0));
915
916 // Server sends the response headers.
917 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
918
919 size_t spdy_response_headers_frame_length;
920 QuicStreamOffset offset = 0;
921 ProcessPacket(ConstructResponseHeadersPacket(
922 2, !kFin, response_headers, &spdy_response_headers_frame_length,
923 &offset));
924
925 delegate->WaitUntilNextCallback(); // OnHeadersReceived
926 TestCompletionCallback cb;
927 int rv = delegate->ReadData(cb.callback());
928 EXPECT_EQ(ERR_IO_PENDING, rv);
jri78ec06a2016-03-31 18:19:40929 session()->connection()->CloseConnection(
930 QUIC_NO_ERROR, "test", ConnectionCloseBehavior::SILENT_CLOSE);
xunjieli2608f9b2016-03-14 13:39:23931 delegate->WaitUntilNextCallback(); // OnFailed
932
933 base::MessageLoop::current()->RunUntilIdle();
934
935 EXPECT_EQ(ERR_UNEXPECTED, delegate->ReadData(cb.callback()));
936 EXPECT_EQ(ERR_UNEXPECTED, delegate->error());
937 EXPECT_EQ(0, delegate->on_data_read_count());
938 EXPECT_EQ(0, delegate->on_data_sent_count());
939 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
940 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
941 delegate->GetTotalSentBytes());
942 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
943 delegate->GetTotalReceivedBytes());
944}
945
946TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterReadData) {
947 SetRequest("POST", "/", DEFAULT_PRIORITY);
948 size_t spdy_request_headers_frame_length;
949 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
950 &spdy_request_headers_frame_length));
951 AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
952
953 Initialize();
954
955 BidirectionalStreamRequestInfo request;
956 request.method = "POST";
957 request.url = GURL("http://www.google.com/");
958 request.end_stream_on_headers = false;
959 request.priority = DEFAULT_PRIORITY;
960
961 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:42962 std::unique_ptr<TestDelegateBase> delegate(
xunjieli2608f9b2016-03-14 13:39:23963 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54964 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23965 delegate->WaitUntilNextCallback(); // OnHeadersSent
966
967 // Server acks the request.
968 ProcessPacket(ConstructAckPacket(1, 0, 0));
969
970 // Server sends the response headers.
971 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
972 size_t spdy_response_headers_frame_length;
973 ProcessPacket(ConstructResponseHeadersPacket(
974 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
975
976 delegate->WaitUntilNextCallback(); // OnHeadersReceived
977 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
978
979 // Cancel the stream after ReadData returns ERR_IO_PENDING.
980 TestCompletionCallback cb;
981 EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb.callback()));
982 delegate->CancelStream();
983
984 base::MessageLoop::current()->RunUntilIdle();
985
986 EXPECT_EQ(0, delegate->on_data_read_count());
987 EXPECT_EQ(0, delegate->on_data_sent_count());
988 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
989 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
990 delegate->GetTotalSentBytes());
991 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
992 delegate->GetTotalReceivedBytes());
993}
994
995TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
996 SetRequest("POST", "/", DEFAULT_PRIORITY);
997 size_t spdy_request_headers_frame_length;
998 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
999 &spdy_request_headers_frame_length));
1000 AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
1001
1002 Initialize();
1003
1004 BidirectionalStreamRequestInfo request;
1005 request.method = "POST";
1006 request.url = GURL("http://www.google.com/");
1007 request.end_stream_on_headers = false;
1008 request.priority = DEFAULT_PRIORITY;
1009
1010 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:421011 std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
xunjieli2608f9b2016-03-14 13:39:231012 read_buffer.get(), kReadBufferSize,
1013 DeleteStreamDelegate::ON_HEADERS_RECEIVED, true));
xunjieli5fafe142016-03-23 23:32:541014 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231015 delegate->WaitUntilNextCallback(); // OnHeadersSent
1016
1017 // Server acks the request.
1018 ProcessPacket(ConstructAckPacket(1, 0, 0));
1019
1020 // Server sends the response headers.
1021 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1022
1023 size_t spdy_response_headers_frame_length;
1024 ProcessPacket(ConstructResponseHeadersPacket(
1025 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1026 nullptr));
1027
1028 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1029 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1030
1031 base::MessageLoop::current()->RunUntilIdle();
1032
1033 EXPECT_EQ(0, delegate->on_data_read_count());
1034 EXPECT_EQ(0, delegate->on_data_sent_count());
1035}
1036
1037TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
1038 SetRequest("POST", "/", DEFAULT_PRIORITY);
1039 size_t spdy_request_headers_frame_length;
1040 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1041 &spdy_request_headers_frame_length));
1042 AddWrite(ConstructAckPacket(2, 3, 1));
1043 AddWrite(ConstructRstStreamPacket(3));
1044
1045 Initialize();
1046
1047 BidirectionalStreamRequestInfo request;
1048 request.method = "POST";
1049 request.url = GURL("http://www.google.com/");
1050 request.end_stream_on_headers = false;
1051 request.priority = DEFAULT_PRIORITY;
1052
1053 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:421054 std::unique_ptr<DeleteStreamDelegate> delegate(
xunjieli2608f9b2016-03-14 13:39:231055 new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
1056 DeleteStreamDelegate::ON_DATA_READ, true));
xunjieli5fafe142016-03-23 23:32:541057 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231058 delegate->WaitUntilNextCallback(); // OnHeadersSent
1059
1060 // Server acks the request.
1061 ProcessPacket(ConstructAckPacket(1, 0, 0));
1062
1063 // Server sends the response headers.
1064 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1065
1066 size_t spdy_response_headers_frame_length;
1067 ProcessPacket(ConstructResponseHeadersPacket(
1068 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1069 nullptr));
1070
1071 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1072
1073 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1074
1075 TestCompletionCallback cb;
1076 int rv = delegate->ReadData(cb.callback());
1077 EXPECT_EQ(ERR_IO_PENDING, rv);
1078 const char kResponseBody[] = "Hello world!";
1079 // Server sends data.
1080 ProcessPacket(
1081 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
1082 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
1083
1084 base::MessageLoop::current()->RunUntilIdle();
1085
1086 EXPECT_EQ(1, delegate->on_data_read_count());
1087 EXPECT_EQ(0, delegate->on_data_sent_count());
1088}
1089
1090TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
1091 SetRequest("GET", "/", DEFAULT_PRIORITY);
1092 size_t spdy_request_headers_frame_length;
1093 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
1094 &spdy_request_headers_frame_length));
1095 AddWrite(ConstructAckPacket(2, 3, 1)); // Ack the data packet
1096
1097 Initialize();
1098
1099 BidirectionalStreamRequestInfo request;
1100 request.method = "GET";
1101 request.url = GURL("http://www.google.com/");
1102 request.end_stream_on_headers = true;
1103 request.priority = DEFAULT_PRIORITY;
1104
1105 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
danakjad1777e2016-04-16 00:56:421106 std::unique_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
xunjieli2608f9b2016-03-14 13:39:231107 read_buffer.get(), kReadBufferSize,
1108 DeleteStreamDelegate::ON_TRAILERS_RECEIVED, true));
xunjieli5fafe142016-03-23 23:32:541109 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231110 delegate->WaitUntilNextCallback(); // OnHeadersSent
1111
1112 // Server acks the request.
1113 ProcessPacket(ConstructAckPacket(1, 0, 0));
1114
1115 // Server sends the response headers.
1116 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1117
1118 QuicStreamOffset offset = 0;
1119 size_t spdy_response_headers_frame_length;
1120 ProcessPacket(ConstructResponseHeadersPacket(
1121 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1122 &offset));
1123
1124 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1125
1126 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1127
1128 TestCompletionCallback cb;
1129 int rv = delegate->ReadData(cb.callback());
1130 EXPECT_EQ(ERR_IO_PENDING, rv);
1131 const char kResponseBody[] = "Hello world!";
1132 // Server sends data.
1133 ProcessPacket(
1134 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
1135
1136 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
1137 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
1138
1139 size_t spdy_trailers_frame_length;
1140 SpdyHeaderBlock trailers;
1141 trailers["foo"] = "bar";
1142 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
1143 // Server sends trailers.
1144 ProcessPacket(ConstructResponseTrailersPacket(
1145 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
1146
1147 delegate->WaitUntilNextCallback(); // OnTrailersReceived
1148 trailers.erase(kFinalOffsetHeaderKey);
1149 EXPECT_EQ(trailers, delegate->trailers());
1150
1151 base::MessageLoop::current()->RunUntilIdle();
1152
1153 EXPECT_EQ(1, delegate->on_data_read_count());
1154 EXPECT_EQ(0, delegate->on_data_sent_count());
1155}
1156
1157} // namespace test
1158
1159} // namespace net