Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(244)

Side by Side Diff: net/quic/bidirectional_stream_quic_impl_unittest.cc

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

Powered by Google App Engine
This is Rietveld 408576698