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

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

Powered by Google App Engine
This is Rietveld 408576698