blob: 3b3591b2573c4d639f268042f89c346cd26bb7e9 [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>
8#include <vector>
9
10#include "base/callback_helpers.h"
11#include "base/memory/scoped_ptr.h"
12#include "base/message_loop/message_loop.h"
13#include "base/run_loop.h"
14#include "base/strings/string_number_conversions.h"
martijna4804402016-03-29 08:24:2715#include "net/base/ip_address.h"
xunjieli2608f9b2016-03-14 13:39:2316#include "net/base/net_errors.h"
17#include "net/http/bidirectional_stream_request_info.h"
18#include "net/http/transport_security_state.h"
xunjieli5fafe142016-03-23 23:32:5419#include "net/log/test_net_log.h"
20#include "net/log/test_net_log_util.h"
xunjieli2608f9b2016-03-14 13:39:2321#include "net/quic/crypto/crypto_protocol.h"
22#include "net/quic/crypto/quic_decrypter.h"
23#include "net/quic/crypto/quic_encrypter.h"
24#include "net/quic/crypto/quic_server_info.h"
25#include "net/quic/quic_chromium_client_session.h"
26#include "net/quic/quic_chromium_client_stream.h"
27#include "net/quic/quic_chromium_connection_helper.h"
28#include "net/quic/quic_chromium_packet_reader.h"
29#include "net/quic/quic_chromium_packet_writer.h"
30#include "net/quic/quic_connection.h"
31#include "net/quic/quic_http_utils.h"
32#include "net/quic/spdy_utils.h"
33#include "net/quic/test_tools/crypto_test_utils.h"
34#include "net/quic/test_tools/mock_clock.h"
35#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
36#include "net/quic/test_tools/mock_random.h"
37#include "net/quic/test_tools/quic_connection_peer.h"
38#include "net/quic/test_tools/quic_test_packet_maker.h"
39#include "net/quic/test_tools/quic_test_utils.h"
40#include "net/quic/test_tools/test_task_runner.h"
41#include "net/socket/socket_test_util.h"
42#include "testing/gmock/include/gmock/gmock.h"
43#include "testing/gtest/include/gtest/gtest.h"
44
45namespace net {
46
47namespace test {
48
49namespace {
50
51const char kUploadData[] = "Really nifty data!";
52const char kDefaultServerHostName[] = "www.google.com";
53const uint16_t kDefaultServerPort = 80;
54// Size of the buffer to be allocated for each read.
55const size_t kReadBufferSize = 4096;
56
xunjieli5749218c2016-03-22 16:43:0657class TestDelegateBase : public BidirectionalStreamImpl::Delegate {
xunjieli2608f9b2016-03-14 13:39:2358 public:
59 TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
60 : TestDelegateBase(read_buf,
61 read_buf_len,
62 make_scoped_ptr(new base::Timer(false, false))) {}
63
64 TestDelegateBase(IOBuffer* read_buf,
65 int read_buf_len,
66 scoped_ptr<base::Timer> timer)
67 : read_buf_(read_buf),
68 read_buf_len_(read_buf_len),
69 timer_(std::move(timer)),
70 loop_(nullptr),
71 error_(OK),
72 on_data_read_count_(0),
73 on_data_sent_count_(0),
74 not_expect_callback_(false) {
75 loop_.reset(new base::RunLoop);
76 }
77
78 ~TestDelegateBase() override {}
79
80 void OnHeadersSent() override {
81 CHECK(!not_expect_callback_);
82 loop_->Quit();
83 }
84
85 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
86 CHECK(!not_expect_callback_);
87
88 response_headers_ = response_headers;
89 loop_->Quit();
90 }
91
92 void OnDataRead(int bytes_read) override {
93 CHECK(!not_expect_callback_);
94 CHECK(!callback_.is_null());
95
96 ++on_data_read_count_;
97 CHECK_GE(bytes_read, OK);
98 data_received_.append(read_buf_->data(), bytes_read);
99 base::ResetAndReturn(&callback_).Run(bytes_read);
100 }
101
102 void OnDataSent() override {
103 CHECK(!not_expect_callback_);
104
105 ++on_data_sent_count_;
106 loop_->Quit();
107 }
108
109 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
110 CHECK(!not_expect_callback_);
111
112 trailers_ = trailers;
113 loop_->Quit();
114 }
115
116 void OnFailed(int error) override {
117 CHECK(!not_expect_callback_);
118 CHECK_EQ(OK, error_);
119 CHECK_NE(OK, error);
120
121 error_ = error;
122 loop_->Quit();
123 }
124
125 void Start(const BidirectionalStreamRequestInfo* request_info,
126 const BoundNetLog& net_log,
127 const base::WeakPtr<QuicChromiumClientSession> session) {
128 stream_job_.reset(new BidirectionalStreamQuicImpl(session));
129 stream_job_->Start(request_info, net_log, this, nullptr);
130 }
131
132 void SendData(IOBuffer* data, int length, bool end_of_stream) {
133 not_expect_callback_ = true;
134 stream_job_->SendData(data, length, end_of_stream);
135 not_expect_callback_ = false;
136 }
137
138 // Waits until next Delegate callback.
139 void WaitUntilNextCallback() {
140 loop_->Run();
141 loop_.reset(new base::RunLoop);
142 }
143
144 // Calls ReadData on the |stream_| and updates |data_received_|.
145 int ReadData(const CompletionCallback& callback) {
146 not_expect_callback_ = true;
147 int rv = stream_job_->ReadData(read_buf_.get(), read_buf_len_);
148 not_expect_callback_ = false;
149 if (rv > 0)
150 data_received_.append(read_buf_->data(), rv);
151 if (rv == ERR_IO_PENDING)
152 callback_ = callback;
153 return rv;
154 }
155
156 // Cancels |stream_|.
157 void CancelStream() { stream_job_->Cancel(); }
158
159 NextProto GetProtocol() const { return stream_job_->GetProtocol(); }
160
161 int64_t GetTotalReceivedBytes() const {
162 return stream_job_->GetTotalReceivedBytes();
163 }
164
165 int64_t GetTotalSentBytes() const { return stream_job_->GetTotalSentBytes(); }
166
167 // Const getters for internal states.
168 const std::string& data_received() const { return data_received_; }
169 int error() const { return error_; }
170 const SpdyHeaderBlock& response_headers() const { return response_headers_; }
171 const SpdyHeaderBlock& trailers() const { return trailers_; }
172 int on_data_read_count() const { return on_data_read_count_; }
173 int on_data_sent_count() const { return on_data_sent_count_; }
174
175 protected:
176 // Quits |loop_|.
177 void QuitLoop() { loop_->Quit(); }
178
179 // Deletes |stream_|.
180 void DeleteStream() { stream_job_.reset(); }
181
182 private:
183 scoped_ptr<BidirectionalStreamQuicImpl> stream_job_;
184 scoped_refptr<IOBuffer> read_buf_;
185 int read_buf_len_;
186 scoped_ptr<base::Timer> timer_;
187 std::string data_received_;
188 scoped_ptr<base::RunLoop> loop_;
189 SpdyHeaderBlock response_headers_;
190 SpdyHeaderBlock trailers_;
191 int error_;
192 int on_data_read_count_;
193 int on_data_sent_count_;
194 // This is to ensure that delegate callback is not invoked synchronously when
195 // calling into |stream_|.
196 bool not_expect_callback_;
197 CompletionCallback callback_;
198
199 DISALLOW_COPY_AND_ASSIGN(TestDelegateBase);
200};
201
202// A delegate that deletes the stream in a particular callback.
203class DeleteStreamDelegate : public TestDelegateBase {
204 public:
205 // Specifies in which callback the stream can be deleted.
206 enum Phase {
207 ON_HEADERS_RECEIVED,
208 ON_DATA_READ,
209 ON_TRAILERS_RECEIVED,
210 ON_FAILED,
211 };
212
213 DeleteStreamDelegate(IOBuffer* buf, int buf_len, Phase phase, bool do_cancel)
214 : TestDelegateBase(buf, buf_len), phase_(phase), do_cancel_(do_cancel) {}
215 ~DeleteStreamDelegate() override {}
216
217 void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
218 if (phase_ == ON_HEADERS_RECEIVED) {
219 DeleteStream();
220 }
221 TestDelegateBase::OnHeadersReceived(response_headers);
222 }
223
224 void OnDataSent() override { NOTREACHED(); }
225
226 void OnDataRead(int bytes_read) override {
227 DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
228 if (phase_ == ON_DATA_READ)
229 DeleteStream();
230 TestDelegateBase::OnDataRead(bytes_read);
231 }
232
233 void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
234 DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
235 DCHECK_NE(ON_DATA_READ, phase_);
236 if (phase_ == ON_TRAILERS_RECEIVED)
237 DeleteStream();
238 TestDelegateBase::OnTrailersReceived(trailers);
239 }
240
241 void OnFailed(int error) override {
242 DCHECK_EQ(ON_FAILED, phase_);
243 DeleteStream();
244 TestDelegateBase::OnFailed(error);
245 }
246
247 private:
248 // Indicates in which callback the delegate should cancel or delete the
249 // stream.
250 Phase phase_;
251 // Indicates whether to cancel or delete the stream.
252 bool do_cancel_;
253
254 DISALLOW_COPY_AND_ASSIGN(DeleteStreamDelegate);
255};
256
257} // namespace
258
259class BidirectionalStreamQuicImplTest
260 : public ::testing::TestWithParam<QuicVersion> {
261 protected:
262 static const bool kFin = true;
263 static const bool kIncludeVersion = true;
264 static const bool kIncludeCongestionFeedback = true;
265
266 // Holds a packet to be written to the wire, and the IO mode that should
267 // be used by the mock socket when performing the write.
268 struct PacketToWrite {
jokulikf2bd55c52016-03-24 22:35:30269 PacketToWrite(IoMode mode, QuicReceivedPacket* packet)
xunjieli2608f9b2016-03-14 13:39:23270 : mode(mode), packet(packet) {}
271 PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
272 IoMode mode;
jokulikf2bd55c52016-03-24 22:35:30273 QuicReceivedPacket* packet;
xunjieli2608f9b2016-03-14 13:39:23274 int rv;
275 };
276
277 BidirectionalStreamQuicImplTest()
xunjieli5fafe142016-03-23 23:32:54278 : crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
xunjieli2608f9b2016-03-14 13:39:23279 read_buffer_(new IOBufferWithSize(4096)),
280 connection_id_(2),
281 stream_id_(kClientDataStreamId1),
282 maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
283 random_generator_(0) {
martijna4804402016-03-29 08:24:27284 IPAddress ip(192, 0, 2, 33);
xunjieli2608f9b2016-03-14 13:39:23285 peer_addr_ = IPEndPoint(ip, 443);
286 self_addr_ = IPEndPoint(ip, 8435);
287 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
288 }
289
290 ~BidirectionalStreamQuicImplTest() {
291 session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
292 for (size_t i = 0; i < writes_.size(); i++) {
293 delete writes_[i].packet;
294 }
295 }
296
297 void TearDown() override {
298 EXPECT_TRUE(socket_data_->AllReadDataConsumed());
299 EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
300 }
301
302 // Adds a packet to the list of expected writes.
jokulikf2bd55c52016-03-24 22:35:30303 void AddWrite(scoped_ptr<QuicReceivedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23304 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
305 }
306
jokulikf2bd55c52016-03-24 22:35:30307 void ProcessPacket(scoped_ptr<QuicReceivedPacket> packet) {
xunjieli2608f9b2016-03-14 13:39:23308 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
309 }
310
311 // Configures the test fixture to use the list of expected writes.
312 void Initialize() {
313 mock_writes_.reset(new MockWrite[writes_.size()]);
314 for (size_t i = 0; i < writes_.size(); i++) {
315 if (writes_[i].packet == nullptr) {
316 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
317 } else {
318 mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
319 writes_[i].packet->length());
320 }
321 };
322
323 socket_data_.reset(new StaticSocketDataProvider(
324 nullptr, 0, mock_writes_.get(), writes_.size()));
325
xunjielib53b38c2016-03-24 15:54:36326 scoped_ptr<MockUDPClientSocket> socket(new MockUDPClientSocket(
327 socket_data_.get(), net_log().bound().net_log()));
xunjieli2608f9b2016-03-14 13:39:23328 socket->Connect(peer_addr_);
329 runner_ = new TestTaskRunner(&clock_);
330 helper_.reset(new QuicChromiumConnectionHelper(runner_.get(), &clock_,
331 &random_generator_));
332 connection_ = new QuicConnection(
333 connection_id_, peer_addr_, helper_.get(),
xunjielib53b38c2016-03-24 15:54:36334 new QuicChromiumPacketWriter(socket.get()), true /* owns_writer */,
xunjieli2608f9b2016-03-14 13:39:23335 Perspective::IS_CLIENT, SupportedVersions(GetParam()));
336
337 session_.reset(new QuicChromiumClientSession(
xunjielib53b38c2016-03-24 15:54:36338 connection_, std::move(socket),
xunjieli2608f9b2016-03-14 13:39:23339 /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
340 &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
341 QuicServerId(kDefaultServerHostName, kDefaultServerPort,
342 PRIVACY_MODE_DISABLED),
343 kQuicYieldAfterPacketsRead,
344 QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
345 /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
346 "CONNECTION_UNKNOWN", base::TimeTicks::Now(), &push_promise_index_,
347 base::ThreadTaskRunnerHandle::Get().get(),
xunjieli5fafe142016-03-23 23:32:54348 /*socket_performance_watcher=*/nullptr, net_log().bound().net_log()));
xunjieli2608f9b2016-03-14 13:39:23349 session_->Initialize();
350 session_->GetCryptoStream()->CryptoConnect();
351 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
352 }
353
354 void SetRequest(const std::string& method,
355 const std::string& path,
356 RequestPriority priority) {
357 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
358 }
359
360 SpdyHeaderBlock ConstructResponseHeaders(const std::string& response_code) {
361 return maker_.GetResponseHeaders(response_code);
362 }
363
jokulikf2bd55c52016-03-24 22:35:30364 scoped_ptr<QuicReceivedPacket> ConstructDataPacket(
xunjieli2608f9b2016-03-14 13:39:23365 QuicPacketNumber packet_number,
366 bool should_include_version,
367 bool fin,
368 QuicStreamOffset offset,
369 base::StringPiece data) {
jokulikf2bd55c52016-03-24 22:35:30370 scoped_ptr<QuicReceivedPacket> packet(maker_.MakeDataPacket(
xunjieli2608f9b2016-03-14 13:39:23371 packet_number, stream_id_, should_include_version, fin, offset, data));
372 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
373 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
374 return packet;
375 }
376
jokulikf2bd55c52016-03-24 22:35:30377 scoped_ptr<QuicReceivedPacket> ConstructRequestHeadersPacket(
xunjieli2608f9b2016-03-14 13:39:23378 QuicPacketNumber packet_number,
379 bool fin,
380 RequestPriority request_priority,
381 size_t* spdy_headers_frame_length) {
382 SpdyPriority priority =
383 ConvertRequestPriorityToQuicPriority(request_priority);
384 return maker_.MakeRequestHeadersPacket(
385 packet_number, stream_id_, kIncludeVersion, fin, priority,
386 request_headers_, spdy_headers_frame_length);
387 }
388
jokulikf2bd55c52016-03-24 22:35:30389 scoped_ptr<QuicReceivedPacket> ConstructResponseHeadersPacket(
xunjieli2608f9b2016-03-14 13:39:23390 QuicPacketNumber packet_number,
391 bool fin,
392 const SpdyHeaderBlock& response_headers,
393 size_t* spdy_headers_frame_length,
394 QuicStreamOffset* offset) {
395 return maker_.MakeResponseHeadersPacket(
396 packet_number, stream_id_, !kIncludeVersion, fin, response_headers,
397 spdy_headers_frame_length, offset);
398 }
399
jokulikf2bd55c52016-03-24 22:35:30400 scoped_ptr<QuicReceivedPacket> ConstructResponseTrailersPacket(
xunjieli2608f9b2016-03-14 13:39:23401 QuicPacketNumber packet_number,
402 bool fin,
403 const SpdyHeaderBlock& trailers,
404 size_t* spdy_headers_frame_length,
405 QuicStreamOffset* offset) {
406 return maker_.MakeResponseHeadersPacket(packet_number, stream_id_,
407 !kIncludeVersion, fin, trailers,
408 spdy_headers_frame_length, offset);
409 }
410
jokulikf2bd55c52016-03-24 22:35:30411 scoped_ptr<QuicReceivedPacket> ConstructRstStreamPacket(
xunjieli2608f9b2016-03-14 13:39:23412 QuicPacketNumber packet_number) {
413 return ConstructRstStreamCancelledPacket(packet_number, 0);
414 }
415
jokulikf2bd55c52016-03-24 22:35:30416 scoped_ptr<QuicReceivedPacket> ConstructRstStreamCancelledPacket(
xunjieli2608f9b2016-03-14 13:39:23417 QuicPacketNumber packet_number,
418 size_t bytes_written) {
jokulikf2bd55c52016-03-24 22:35:30419 scoped_ptr<QuicReceivedPacket> packet(
xunjieli2608f9b2016-03-14 13:39:23420 maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
421 QUIC_STREAM_CANCELLED, bytes_written));
422 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
423 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
424 return packet;
425 }
426
jokulikf2bd55c52016-03-24 22:35:30427 scoped_ptr<QuicReceivedPacket> ConstructAckAndRstStreamPacket(
xunjieli2608f9b2016-03-14 13:39:23428 QuicPacketNumber packet_number,
429 QuicPacketNumber largest_received,
430 QuicPacketNumber ack_least_unacked,
431 QuicPacketNumber stop_least_unacked) {
432 return maker_.MakeAckAndRstPacket(
433 packet_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
434 largest_received, ack_least_unacked, stop_least_unacked,
435 !kIncludeCongestionFeedback);
436 }
437
jokulikf2bd55c52016-03-24 22:35:30438 scoped_ptr<QuicReceivedPacket> ConstructAckAndDataPacket(
xunjieli2608f9b2016-03-14 13:39:23439 QuicPacketNumber packet_number,
440 bool should_include_version,
441 QuicPacketNumber largest_received,
442 QuicPacketNumber least_unacked,
443 bool fin,
444 QuicStreamOffset offset,
445 base::StringPiece data) {
jokulikf2bd55c52016-03-24 22:35:30446 scoped_ptr<QuicReceivedPacket> packet(maker_.MakeAckAndDataPacket(
xunjieli2608f9b2016-03-14 13:39:23447 packet_number, should_include_version, stream_id_, largest_received,
448 least_unacked, fin, offset, data));
449 DVLOG(2) << "packet(" << packet_number << "): " << std::endl
450 << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
451 return packet;
452 }
453
jokulikf2bd55c52016-03-24 22:35:30454 scoped_ptr<QuicReceivedPacket> ConstructAckPacket(
xunjieli2608f9b2016-03-14 13:39:23455 QuicPacketNumber packet_number,
456 QuicPacketNumber largest_received,
457 QuicPacketNumber least_unacked) {
458 return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
459 !kIncludeCongestionFeedback);
460 }
461
xunjieli5fafe142016-03-23 23:32:54462 const BoundTestNetLog& net_log() const { return net_log_; }
xunjieli2608f9b2016-03-14 13:39:23463
464 QuicChromiumClientSession* session() const { return session_.get(); }
465
466 private:
xunjieli5fafe142016-03-23 23:32:54467 BoundTestNetLog net_log_;
xunjieli2608f9b2016-03-14 13:39:23468 scoped_refptr<TestTaskRunner> runner_;
469 scoped_ptr<MockWrite[]> mock_writes_;
470 MockClock clock_;
471 QuicConnection* connection_;
472 scoped_ptr<QuicChromiumConnectionHelper> helper_;
473 TransportSecurityState transport_security_state_;
474 scoped_ptr<QuicChromiumClientSession> session_;
475 QuicCryptoClientConfig crypto_config_;
476 HttpRequestHeaders headers_;
477 HttpResponseInfo response_;
478 scoped_refptr<IOBufferWithSize> read_buffer_;
479 SpdyHeaderBlock request_headers_;
480 const QuicConnectionId connection_id_;
481 const QuicStreamId stream_id_;
482 QuicTestPacketMaker maker_;
483 IPEndPoint self_addr_;
484 IPEndPoint peer_addr_;
485 MockRandom random_generator_;
486 MockCryptoClientStreamFactory crypto_client_stream_factory_;
487 scoped_ptr<StaticSocketDataProvider> socket_data_;
488 std::vector<PacketToWrite> writes_;
489 QuicClientPushPromiseIndex push_promise_index_;
490};
491
492INSTANTIATE_TEST_CASE_P(Version,
493 BidirectionalStreamQuicImplTest,
494 ::testing::ValuesIn(QuicSupportedVersions()));
495
496TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
497 SetRequest("GET", "/", DEFAULT_PRIORITY);
498 size_t spdy_request_headers_frame_length;
499 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
500 &spdy_request_headers_frame_length));
501
502 AddWrite(ConstructAckPacket(2, 3, 1));
503 Initialize();
504
505 BidirectionalStreamRequestInfo request;
506 request.method = "GET";
507 request.url = GURL("http://www.google.com/");
508 request.end_stream_on_headers = true;
509 request.priority = DEFAULT_PRIORITY;
510
511 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
512 scoped_ptr<TestDelegateBase> delegate(
513 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54514 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23515 delegate->WaitUntilNextCallback(); // OnHeadersSent
516
517 // Server acks the request.
518 ProcessPacket(ConstructAckPacket(1, 0, 0));
519
520 // Server sends the response headers.
521 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
522
523 size_t spdy_response_headers_frame_length;
524 QuicStreamOffset offset = 0;
525 ProcessPacket(ConstructResponseHeadersPacket(
526 2, !kFin, response_headers, &spdy_response_headers_frame_length,
527 &offset));
528
529 delegate->WaitUntilNextCallback(); // OnHeadersReceived
530 TestCompletionCallback cb;
531 int rv = delegate->ReadData(cb.callback());
532 EXPECT_EQ(ERR_IO_PENDING, rv);
533 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
534 const char kResponseBody[] = "Hello world!";
535 // Server sends data.
536 ProcessPacket(
537 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
538 EXPECT_EQ(12, cb.WaitForResult());
539
540 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
541 TestCompletionCallback cb2;
542 EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb2.callback()));
543
544 SpdyHeaderBlock trailers;
545 size_t spdy_trailers_frame_length;
546 trailers["foo"] = "bar";
547 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
548 // Server sends trailers.
549 ProcessPacket(ConstructResponseTrailersPacket(
550 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
551
552 delegate->WaitUntilNextCallback(); // OnTrailersReceived
553 EXPECT_EQ(OK, cb2.WaitForResult());
554 trailers.erase(kFinalOffsetHeaderKey);
555 EXPECT_EQ(trailers, delegate->trailers());
556
557 EXPECT_EQ(OK, delegate->ReadData(cb2.callback()));
558 base::MessageLoop::current()->RunUntilIdle();
559
560 EXPECT_EQ(2, delegate->on_data_read_count());
561 EXPECT_EQ(0, delegate->on_data_sent_count());
562 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
563 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
564 delegate->GetTotalSentBytes());
565 EXPECT_EQ(
566 static_cast<int64_t>(spdy_response_headers_frame_length +
567 strlen(kResponseBody) + spdy_trailers_frame_length),
568 delegate->GetTotalReceivedBytes());
xunjieli5fafe142016-03-23 23:32:54569 // Check that NetLog was filled as expected.
570 TestNetLogEntry::List entries;
571 net_log().GetEntries(&entries);
572 size_t pos = ExpectLogContainsSomewhere(
573 entries, /*min_offset=*/0,
574 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
575 NetLog::PHASE_NONE);
576 pos = ExpectLogContainsSomewhere(
577 entries, /*min_offset=*/pos,
578 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
579 NetLog::PHASE_NONE);
580 ExpectLogContainsSomewhere(
581 entries, /*min_offset=*/pos,
582 NetLog::TYPE_QUIC_CHROMIUM_CLIENT_STREAM_SEND_REQUEST_HEADERS,
583 NetLog::PHASE_NONE);
xunjieli2608f9b2016-03-14 13:39:23584}
585
586TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
587 SetRequest("POST", "/", DEFAULT_PRIORITY);
588 size_t spdy_request_headers_frame_length;
589 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
590 &spdy_request_headers_frame_length));
591 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
592 AddWrite(ConstructAckPacket(3, 3, 1));
593
594 Initialize();
595
596 BidirectionalStreamRequestInfo request;
597 request.method = "POST";
598 request.url = GURL("http://www.google.com/");
599 request.end_stream_on_headers = false;
600 request.priority = DEFAULT_PRIORITY;
601
602 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
603 scoped_ptr<TestDelegateBase> delegate(
604 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54605 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23606 delegate->WaitUntilNextCallback(); // OnHeadersSent
607
608 // Send a DATA frame.
609 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
610
611 delegate->SendData(buf.get(), buf->size(), true);
612 delegate->WaitUntilNextCallback(); // OnDataSent
613
614 // Server acks the request.
615 ProcessPacket(ConstructAckPacket(1, 0, 0));
616
617 // Server sends the response headers.
618 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
619 size_t spdy_response_headers_frame_length;
620 QuicStreamOffset offset = 0;
621 ProcessPacket(ConstructResponseHeadersPacket(
622 2, !kFin, response_headers, &spdy_response_headers_frame_length,
623 &offset));
624
625 delegate->WaitUntilNextCallback(); // OnHeadersReceived
626 TestCompletionCallback cb;
627 int rv = delegate->ReadData(cb.callback());
628 EXPECT_EQ(ERR_IO_PENDING, rv);
629 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
630 const char kResponseBody[] = "Hello world!";
631 // Server sends data.
632 ProcessPacket(
633 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
634
635 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult());
636
637 size_t spdy_trailers_frame_length;
638 SpdyHeaderBlock trailers;
639 trailers["foo"] = "bar";
640 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
641 // Server sends trailers.
642 ProcessPacket(ConstructResponseTrailersPacket(
643 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
644
645 delegate->WaitUntilNextCallback(); // OnTrailersReceived
646 trailers.erase(kFinalOffsetHeaderKey);
647 EXPECT_EQ(trailers, delegate->trailers());
648 EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
649
650 EXPECT_EQ(1, delegate->on_data_read_count());
651 EXPECT_EQ(1, delegate->on_data_sent_count());
652 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
653 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
654 strlen(kUploadData)),
655 delegate->GetTotalSentBytes());
656 EXPECT_EQ(
657 static_cast<int64_t>(spdy_response_headers_frame_length +
658 strlen(kResponseBody) + spdy_trailers_frame_length),
659 delegate->GetTotalReceivedBytes());
660}
661
662TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
663 SetRequest("POST", "/", DEFAULT_PRIORITY);
664 size_t spdy_request_headers_frame_length;
665 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
666 &spdy_request_headers_frame_length));
667 AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
668 kUploadData));
669 AddWrite(ConstructAckAndDataPacket(3, !kIncludeVersion, 3, 3, kFin,
670 strlen(kUploadData), kUploadData));
671 Initialize();
672
673 BidirectionalStreamRequestInfo request;
674 request.method = "POST";
675 request.url = GURL("http://www.google.com/");
676 request.end_stream_on_headers = false;
677 request.priority = DEFAULT_PRIORITY;
678
679 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
680 scoped_ptr<TestDelegateBase> delegate(
681 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54682 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23683 delegate->WaitUntilNextCallback(); // OnHeadersSent
684
685 // Server acks the request.
686 ProcessPacket(ConstructAckPacket(1, 0, 0));
687
688 // Server sends the response headers.
689 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
690 size_t spdy_response_headers_frame_length;
691 ProcessPacket(ConstructResponseHeadersPacket(
692 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
693
694 delegate->WaitUntilNextCallback(); // OnHeadersReceived
695 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
696
697 // Client sends a data packet.
698 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
699
700 delegate->SendData(buf.get(), buf->size(), false);
701 delegate->WaitUntilNextCallback(); // OnDataSent
702
703 TestCompletionCallback cb;
704 int rv = delegate->ReadData(cb.callback());
705 EXPECT_EQ(ERR_IO_PENDING, rv);
706 const char kResponseBody[] = "Hello world!";
707
708 // Server sends a data packet.
709 ProcessPacket(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, !kFin, 0,
710 kResponseBody));
711
712 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
713 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
714
715 // Client sends a data packet.
716 delegate->SendData(buf.get(), buf->size(), true);
717 delegate->WaitUntilNextCallback(); // OnDataSent
718
719 TestCompletionCallback cb2;
720 rv = delegate->ReadData(cb2.callback());
721 EXPECT_EQ(ERR_IO_PENDING, rv);
722 ProcessPacket(ConstructAckAndDataPacket(
723 4, !kIncludeVersion, 3, 1, kFin, strlen(kResponseBody), kResponseBody));
724
725 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb2.WaitForResult());
726
727 std::string expected_body(kResponseBody);
728 expected_body.append(kResponseBody);
729 EXPECT_EQ(expected_body, delegate->data_received());
730
731 EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
732 EXPECT_EQ(2, delegate->on_data_read_count());
733 EXPECT_EQ(2, delegate->on_data_sent_count());
734 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
735 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
736 2 * strlen(kUploadData)),
737 delegate->GetTotalSentBytes());
738 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
739 2 * strlen(kResponseBody)),
740 delegate->GetTotalReceivedBytes());
741}
742
743TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
744 SetRequest("GET", "/", DEFAULT_PRIORITY);
745 size_t spdy_request_headers_frame_length;
746 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
747 &spdy_request_headers_frame_length));
748 Initialize();
749
750 BidirectionalStreamRequestInfo request;
751 request.method = "GET";
752 request.url = GURL("http://www.google.com/");
753 request.end_stream_on_headers = true;
754 request.priority = DEFAULT_PRIORITY;
755
756 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
757 scoped_ptr<TestDelegateBase> delegate(
758 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54759 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23760 delegate->WaitUntilNextCallback(); // OnHeadersSent
761
762 // Server sends a Rst.
763 ProcessPacket(ConstructRstStreamPacket(1));
764
765 delegate->WaitUntilNextCallback(); // OnFailed
766 TestCompletionCallback cb;
767 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
768
769 base::MessageLoop::current()->RunUntilIdle();
770
771 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
772 EXPECT_EQ(0, delegate->on_data_read_count());
773 EXPECT_EQ(0, delegate->on_data_sent_count());
774 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
775 delegate->GetTotalSentBytes());
776 EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
777}
778
779TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
780 SetRequest("GET", "/", DEFAULT_PRIORITY);
781 size_t spdy_request_headers_frame_length;
782 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
783 &spdy_request_headers_frame_length));
784 // Why does QUIC ack Rst? Is this expected?
785 AddWrite(ConstructAckPacket(2, 3, 1));
786
787 Initialize();
788
789 BidirectionalStreamRequestInfo request;
790 request.method = "GET";
791 request.url = GURL("http://www.google.com/");
792 request.end_stream_on_headers = true;
793 request.priority = DEFAULT_PRIORITY;
794
795 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
796 scoped_ptr<TestDelegateBase> delegate(
797 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54798 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23799 delegate->WaitUntilNextCallback(); // OnHeadersSent
800
801 // Server acks the request.
802 ProcessPacket(ConstructAckPacket(1, 0, 0));
803
804 // Server sends the response headers.
805 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
806
807 size_t spdy_response_headers_frame_length;
808 QuicStreamOffset offset = 0;
809 ProcessPacket(ConstructResponseHeadersPacket(
810 2, !kFin, response_headers, &spdy_response_headers_frame_length,
811 &offset));
812
813 delegate->WaitUntilNextCallback(); // OnHeadersReceived
814 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
815
816 TestCompletionCallback cb;
817 int rv = delegate->ReadData(cb.callback());
818 EXPECT_EQ(ERR_IO_PENDING, rv);
819
820 // Server sends a Rst.
821 ProcessPacket(ConstructRstStreamPacket(3));
822
823 delegate->WaitUntilNextCallback(); // OnFailed
824
825 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
826 EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
827 EXPECT_EQ(0, delegate->on_data_read_count());
828 EXPECT_EQ(0, delegate->on_data_sent_count());
829 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
830 delegate->GetTotalSentBytes());
831 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
832 delegate->GetTotalReceivedBytes());
833}
834
835TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterSendData) {
836 SetRequest("POST", "/", DEFAULT_PRIORITY);
837 size_t spdy_request_headers_frame_length;
838 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
839 &spdy_request_headers_frame_length));
840 AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
841 kUploadData));
842 AddWrite(ConstructRstStreamCancelledPacket(3, strlen(kUploadData)));
843
844 Initialize();
845
846 BidirectionalStreamRequestInfo request;
847 request.method = "POST";
848 request.url = GURL("http://www.google.com/");
849 request.end_stream_on_headers = false;
850 request.priority = DEFAULT_PRIORITY;
851
852 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
853 scoped_ptr<TestDelegateBase> delegate(
854 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54855 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23856 delegate->WaitUntilNextCallback(); // OnHeadersSent
857
858 // Server acks the request.
859 ProcessPacket(ConstructAckPacket(1, 0, 0));
860
861 // Server sends the response headers.
862 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
863 size_t spdy_response_headers_frame_length;
864 ProcessPacket(ConstructResponseHeadersPacket(
865 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
866
867 delegate->WaitUntilNextCallback(); // OnHeadersReceived
868 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
869
870 // Send a DATA frame.
871 scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
872
873 delegate->SendData(buf.get(), buf->size(), false);
874 delegate->WaitUntilNextCallback(); // OnDataSent
875
876 delegate->CancelStream();
877 base::MessageLoop::current()->RunUntilIdle();
878
879 EXPECT_EQ(0, delegate->on_data_read_count());
880 EXPECT_EQ(1, delegate->on_data_sent_count());
881 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
882 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
883 strlen(kUploadData)),
884 delegate->GetTotalSentBytes());
885 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
886 delegate->GetTotalReceivedBytes());
887}
888
889TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
890 SetRequest("GET", "/", DEFAULT_PRIORITY);
891 size_t spdy_request_headers_frame_length;
892 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
893 &spdy_request_headers_frame_length));
894 Initialize();
895
896 BidirectionalStreamRequestInfo request;
897 request.method = "GET";
898 request.url = GURL("http://www.google.com/");
899 request.end_stream_on_headers = true;
900 request.priority = DEFAULT_PRIORITY;
901
902 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
903 scoped_ptr<TestDelegateBase> delegate(
904 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54905 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23906 delegate->WaitUntilNextCallback(); // OnHeadersSent
907
908 // Server acks the request.
909 ProcessPacket(ConstructAckPacket(1, 0, 0));
910
911 // Server sends the response headers.
912 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
913
914 size_t spdy_response_headers_frame_length;
915 QuicStreamOffset offset = 0;
916 ProcessPacket(ConstructResponseHeadersPacket(
917 2, !kFin, response_headers, &spdy_response_headers_frame_length,
918 &offset));
919
920 delegate->WaitUntilNextCallback(); // OnHeadersReceived
921 TestCompletionCallback cb;
922 int rv = delegate->ReadData(cb.callback());
923 EXPECT_EQ(ERR_IO_PENDING, rv);
924 session()->connection()->CloseConnection(QUIC_NO_ERROR,
925 ConnectionCloseSource::FROM_PEER);
926 delegate->WaitUntilNextCallback(); // OnFailed
927
928 base::MessageLoop::current()->RunUntilIdle();
929
930 EXPECT_EQ(ERR_UNEXPECTED, delegate->ReadData(cb.callback()));
931 EXPECT_EQ(ERR_UNEXPECTED, delegate->error());
932 EXPECT_EQ(0, delegate->on_data_read_count());
933 EXPECT_EQ(0, delegate->on_data_sent_count());
934 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
935 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
936 delegate->GetTotalSentBytes());
937 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
938 delegate->GetTotalReceivedBytes());
939}
940
941TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterReadData) {
942 SetRequest("POST", "/", DEFAULT_PRIORITY);
943 size_t spdy_request_headers_frame_length;
944 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
945 &spdy_request_headers_frame_length));
946 AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
947
948 Initialize();
949
950 BidirectionalStreamRequestInfo request;
951 request.method = "POST";
952 request.url = GURL("http://www.google.com/");
953 request.end_stream_on_headers = false;
954 request.priority = DEFAULT_PRIORITY;
955
956 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
957 scoped_ptr<TestDelegateBase> delegate(
958 new TestDelegateBase(read_buffer.get(), kReadBufferSize));
xunjieli5fafe142016-03-23 23:32:54959 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:23960 delegate->WaitUntilNextCallback(); // OnHeadersSent
961
962 // Server acks the request.
963 ProcessPacket(ConstructAckPacket(1, 0, 0));
964
965 // Server sends the response headers.
966 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
967 size_t spdy_response_headers_frame_length;
968 ProcessPacket(ConstructResponseHeadersPacket(
969 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
970
971 delegate->WaitUntilNextCallback(); // OnHeadersReceived
972 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
973
974 // Cancel the stream after ReadData returns ERR_IO_PENDING.
975 TestCompletionCallback cb;
976 EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb.callback()));
977 delegate->CancelStream();
978
979 base::MessageLoop::current()->RunUntilIdle();
980
981 EXPECT_EQ(0, delegate->on_data_read_count());
982 EXPECT_EQ(0, delegate->on_data_sent_count());
983 EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
984 EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
985 delegate->GetTotalSentBytes());
986 EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
987 delegate->GetTotalReceivedBytes());
988}
989
990TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
991 SetRequest("POST", "/", DEFAULT_PRIORITY);
992 size_t spdy_request_headers_frame_length;
993 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
994 &spdy_request_headers_frame_length));
995 AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
996
997 Initialize();
998
999 BidirectionalStreamRequestInfo request;
1000 request.method = "POST";
1001 request.url = GURL("http://www.google.com/");
1002 request.end_stream_on_headers = false;
1003 request.priority = DEFAULT_PRIORITY;
1004
1005 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
1006 scoped_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
1007 read_buffer.get(), kReadBufferSize,
1008 DeleteStreamDelegate::ON_HEADERS_RECEIVED, true));
xunjieli5fafe142016-03-23 23:32:541009 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231010 delegate->WaitUntilNextCallback(); // OnHeadersSent
1011
1012 // Server acks the request.
1013 ProcessPacket(ConstructAckPacket(1, 0, 0));
1014
1015 // Server sends the response headers.
1016 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1017
1018 size_t spdy_response_headers_frame_length;
1019 ProcessPacket(ConstructResponseHeadersPacket(
1020 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1021 nullptr));
1022
1023 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1024 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1025
1026 base::MessageLoop::current()->RunUntilIdle();
1027
1028 EXPECT_EQ(0, delegate->on_data_read_count());
1029 EXPECT_EQ(0, delegate->on_data_sent_count());
1030}
1031
1032TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
1033 SetRequest("POST", "/", DEFAULT_PRIORITY);
1034 size_t spdy_request_headers_frame_length;
1035 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
1036 &spdy_request_headers_frame_length));
1037 AddWrite(ConstructAckPacket(2, 3, 1));
1038 AddWrite(ConstructRstStreamPacket(3));
1039
1040 Initialize();
1041
1042 BidirectionalStreamRequestInfo request;
1043 request.method = "POST";
1044 request.url = GURL("http://www.google.com/");
1045 request.end_stream_on_headers = false;
1046 request.priority = DEFAULT_PRIORITY;
1047
1048 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
1049 scoped_ptr<DeleteStreamDelegate> delegate(
1050 new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
1051 DeleteStreamDelegate::ON_DATA_READ, true));
xunjieli5fafe142016-03-23 23:32:541052 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231053 delegate->WaitUntilNextCallback(); // OnHeadersSent
1054
1055 // Server acks the request.
1056 ProcessPacket(ConstructAckPacket(1, 0, 0));
1057
1058 // Server sends the response headers.
1059 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1060
1061 size_t spdy_response_headers_frame_length;
1062 ProcessPacket(ConstructResponseHeadersPacket(
1063 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1064 nullptr));
1065
1066 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1067
1068 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1069
1070 TestCompletionCallback cb;
1071 int rv = delegate->ReadData(cb.callback());
1072 EXPECT_EQ(ERR_IO_PENDING, rv);
1073 const char kResponseBody[] = "Hello world!";
1074 // Server sends data.
1075 ProcessPacket(
1076 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
1077 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
1078
1079 base::MessageLoop::current()->RunUntilIdle();
1080
1081 EXPECT_EQ(1, delegate->on_data_read_count());
1082 EXPECT_EQ(0, delegate->on_data_sent_count());
1083}
1084
1085TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
1086 SetRequest("GET", "/", DEFAULT_PRIORITY);
1087 size_t spdy_request_headers_frame_length;
1088 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
1089 &spdy_request_headers_frame_length));
1090 AddWrite(ConstructAckPacket(2, 3, 1)); // Ack the data packet
1091
1092 Initialize();
1093
1094 BidirectionalStreamRequestInfo request;
1095 request.method = "GET";
1096 request.url = GURL("http://www.google.com/");
1097 request.end_stream_on_headers = true;
1098 request.priority = DEFAULT_PRIORITY;
1099
1100 scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
1101 scoped_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
1102 read_buffer.get(), kReadBufferSize,
1103 DeleteStreamDelegate::ON_TRAILERS_RECEIVED, true));
xunjieli5fafe142016-03-23 23:32:541104 delegate->Start(&request, net_log().bound(), session()->GetWeakPtr());
xunjieli2608f9b2016-03-14 13:39:231105 delegate->WaitUntilNextCallback(); // OnHeadersSent
1106
1107 // Server acks the request.
1108 ProcessPacket(ConstructAckPacket(1, 0, 0));
1109
1110 // Server sends the response headers.
1111 SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
1112
1113 QuicStreamOffset offset = 0;
1114 size_t spdy_response_headers_frame_length;
1115 ProcessPacket(ConstructResponseHeadersPacket(
1116 2, !kFin, response_headers, &spdy_response_headers_frame_length,
1117 &offset));
1118
1119 delegate->WaitUntilNextCallback(); // OnHeadersReceived
1120
1121 EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
1122
1123 TestCompletionCallback cb;
1124 int rv = delegate->ReadData(cb.callback());
1125 EXPECT_EQ(ERR_IO_PENDING, rv);
1126 const char kResponseBody[] = "Hello world!";
1127 // Server sends data.
1128 ProcessPacket(
1129 ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
1130
1131 EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
1132 EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
1133
1134 size_t spdy_trailers_frame_length;
1135 SpdyHeaderBlock trailers;
1136 trailers["foo"] = "bar";
1137 trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
1138 // Server sends trailers.
1139 ProcessPacket(ConstructResponseTrailersPacket(
1140 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
1141
1142 delegate->WaitUntilNextCallback(); // OnTrailersReceived
1143 trailers.erase(kFinalOffsetHeaderKey);
1144 EXPECT_EQ(trailers, delegate->trailers());
1145
1146 base::MessageLoop::current()->RunUntilIdle();
1147
1148 EXPECT_EQ(1, delegate->on_data_read_count());
1149 EXPECT_EQ(0, delegate->on_data_sent_count());
1150}
1151
1152} // namespace test
1153
1154} // namespace net