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

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

Issue 992733002: Remove //net (except for Android test stuff) and sdch (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 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/quic_http_stream.cc ('k') | net/quic/quic_http_utils.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 (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/quic/quic_http_stream.h"
6
7 #include <vector>
8
9 #include "net/base/chunked_upload_data_stream.h"
10 #include "net/base/elements_upload_data_stream.h"
11 #include "net/base/net_errors.h"
12 #include "net/base/test_completion_callback.h"
13 #include "net/base/upload_bytes_element_reader.h"
14 #include "net/http/http_response_headers.h"
15 #include "net/http/transport_security_state.h"
16 #include "net/quic/congestion_control/send_algorithm_interface.h"
17 #include "net/quic/crypto/crypto_protocol.h"
18 #include "net/quic/crypto/quic_decrypter.h"
19 #include "net/quic/crypto/quic_encrypter.h"
20 #include "net/quic/crypto/quic_server_info.h"
21 #include "net/quic/quic_client_session.h"
22 #include "net/quic/quic_connection.h"
23 #include "net/quic/quic_connection_helper.h"
24 #include "net/quic/quic_default_packet_writer.h"
25 #include "net/quic/quic_http_utils.h"
26 #include "net/quic/quic_reliable_client_stream.h"
27 #include "net/quic/quic_write_blocked_list.h"
28 #include "net/quic/spdy_utils.h"
29 #include "net/quic/test_tools/mock_clock.h"
30 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
31 #include "net/quic/test_tools/mock_random.h"
32 #include "net/quic/test_tools/quic_connection_peer.h"
33 #include "net/quic/test_tools/quic_test_packet_maker.h"
34 #include "net/quic/test_tools/quic_test_utils.h"
35 #include "net/quic/test_tools/test_task_runner.h"
36 #include "net/socket/socket_test_util.h"
37 #include "net/spdy/spdy_frame_builder.h"
38 #include "net/spdy/spdy_framer.h"
39 #include "net/spdy/spdy_http_utils.h"
40 #include "net/spdy/spdy_protocol.h"
41 #include "testing/gmock/include/gmock/gmock.h"
42 #include "testing/gtest/include/gtest/gtest.h"
43
44 using testing::_;
45 using testing::AnyNumber;
46 using testing::Return;
47
48 namespace net {
49 namespace test {
50 namespace {
51
52 const char kUploadData[] = "Really nifty data!";
53 const char kServerHostname[] = "www.google.com";
54 const uint16 kServerPort = 80;
55
56 class TestQuicConnection : public QuicConnection {
57 public:
58 TestQuicConnection(const QuicVersionVector& versions,
59 QuicConnectionId connection_id,
60 IPEndPoint address,
61 QuicConnectionHelper* helper,
62 const QuicConnection::PacketWriterFactory& writer_factory)
63 : QuicConnection(connection_id,
64 address,
65 helper,
66 writer_factory,
67 true /* owns_writer */,
68 false /* is_server */,
69 false /* is_secure */,
70 versions) {
71 }
72
73 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) {
74 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm);
75 }
76 };
77
78 // Subclass of QuicHttpStream that closes itself when the first piece of data
79 // is received.
80 class AutoClosingStream : public QuicHttpStream {
81 public:
82 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session)
83 : QuicHttpStream(session) {
84 }
85
86 int OnDataReceived(const char* data, int length) override {
87 Close(false);
88 return OK;
89 }
90 };
91
92 class TestPacketWriterFactory : public QuicConnection::PacketWriterFactory {
93 public:
94 explicit TestPacketWriterFactory(DatagramClientSocket* socket)
95 : socket_(socket) {}
96 ~TestPacketWriterFactory() override {}
97
98 QuicPacketWriter* Create(QuicConnection* connection) const override {
99 return new QuicDefaultPacketWriter(socket_);
100 }
101
102 private:
103 DatagramClientSocket* socket_;
104 };
105
106 } // namespace
107
108 class QuicHttpStreamPeer {
109 public:
110 static QuicReliableClientStream* GetQuicReliableClientStream(
111 QuicHttpStream* stream) {
112 return stream->stream_;
113 }
114 };
115
116 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> {
117 protected:
118 static const bool kFin = true;
119 static const bool kIncludeVersion = true;
120 static const bool kIncludeCongestionFeedback = true;
121
122 // Holds a packet to be written to the wire, and the IO mode that should
123 // be used by the mock socket when performing the write.
124 struct PacketToWrite {
125 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
126 : mode(mode),
127 packet(packet) {
128 }
129 IoMode mode;
130 QuicEncryptedPacket* packet;
131 };
132
133 QuicHttpStreamTest()
134 : net_log_(BoundNetLog()),
135 use_closing_stream_(false),
136 read_buffer_(new IOBufferWithSize(4096)),
137 connection_id_(2),
138 stream_id_(kClientDataStreamId1),
139 maker_(GetParam(), connection_id_, &clock_),
140 random_generator_(0) {
141 IPAddressNumber ip;
142 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
143 peer_addr_ = IPEndPoint(ip, 443);
144 self_addr_ = IPEndPoint(ip, 8435);
145 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
146 }
147
148 ~QuicHttpStreamTest() {
149 session_->CloseSessionOnError(ERR_ABORTED);
150 for (size_t i = 0; i < writes_.size(); i++) {
151 delete writes_[i].packet;
152 }
153 }
154
155 // Adds a packet to the list of expected writes.
156 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
157 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
158 }
159
160 // Returns the packet to be written at position |pos|.
161 QuicEncryptedPacket* GetWrite(size_t pos) {
162 return writes_[pos].packet;
163 }
164
165 bool AtEof() {
166 return socket_data_->at_read_eof() && socket_data_->at_write_eof();
167 }
168
169 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
170 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
171 }
172
173 // Configures the test fixture to use the list of expected writes.
174 void Initialize() {
175 mock_writes_.reset(new MockWrite[writes_.size()]);
176 for (size_t i = 0; i < writes_.size(); i++) {
177 mock_writes_[i] = MockWrite(writes_[i].mode,
178 writes_[i].packet->data(),
179 writes_[i].packet->length());
180 };
181
182 socket_data_.reset(new StaticSocketDataProvider(
183 nullptr, 0, mock_writes_.get(), writes_.size()));
184
185 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(),
186 net_log_.net_log());
187 socket->Connect(peer_addr_);
188 runner_ = new TestTaskRunner(&clock_);
189 send_algorithm_ = new MockSendAlgorithm();
190 EXPECT_CALL(*send_algorithm_,
191 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true));
192 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly(
193 Return(QuicTime::Delta::Zero()));
194 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly(
195 Return(kMaxPacketSize));
196 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)).
197 WillRepeatedly(Return(QuicTime::Delta::Zero()));
198 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly(
199 Return(QuicBandwidth::Zero()));
200 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _, _)).Times(AnyNumber());
201 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_,
202 &random_generator_));
203 TestPacketWriterFactory writer_factory(socket);
204 connection_ = new TestQuicConnection(SupportedVersions(GetParam()),
205 connection_id_, peer_addr_,
206 helper_.get(), writer_factory);
207 connection_->set_visitor(&visitor_);
208 connection_->SetSendAlgorithm(send_algorithm_);
209 session_.reset(
210 new QuicClientSession(connection_,
211 scoped_ptr<DatagramClientSocket>(socket),
212 nullptr,
213 &transport_security_state_,
214 make_scoped_ptr((QuicServerInfo*)nullptr),
215 DefaultQuicConfig(),
216 base::MessageLoop::current()->
217 message_loop_proxy().get(),
218 nullptr));
219 session_->InitializeSession(QuicServerId(kServerHostname, kServerPort,
220 /*is_secure=*/false,
221 PRIVACY_MODE_DISABLED),
222 &crypto_config_,
223 &crypto_client_stream_factory_);
224 session_->GetCryptoStream()->CryptoConnect();
225 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
226 stream_.reset(use_closing_stream_ ?
227 new AutoClosingStream(session_->GetWeakPtr()) :
228 new QuicHttpStream(session_->GetWeakPtr()));
229 }
230
231 void SetRequest(const std::string& method,
232 const std::string& path,
233 RequestPriority priority) {
234 request_headers_ = maker_.GetRequestHeaders(method, "http", path);
235 }
236
237 void SetResponse(const std::string& status, const std::string& body) {
238 response_headers_ = maker_.GetResponseHeaders(status);
239 response_data_ = body;
240 }
241
242 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
243 QuicPacketSequenceNumber sequence_number,
244 bool should_include_version,
245 bool fin,
246 QuicStreamOffset offset,
247 base::StringPiece data) {
248 return maker_.MakeDataPacket(sequence_number, stream_id_,
249 should_include_version, fin, offset, data);
250 }
251
252 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
253 QuicPacketSequenceNumber sequence_number,
254 bool fin,
255 RequestPriority request_priority) {
256 QuicPriority priority =
257 ConvertRequestPriorityToQuicPriority(request_priority);
258 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id_,
259 kIncludeVersion, fin, priority,
260 request_headers_);
261 }
262
263 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
264 QuicPacketSequenceNumber sequence_number,
265 bool fin) {
266 return maker_.MakeResponseHeadersPacket(
267 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_);
268 }
269
270 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
271 QuicPacketSequenceNumber sequence_number) {
272 return maker_.MakeRstPacket(
273 sequence_number, true, stream_id_,
274 AdjustErrorForVersion(QUIC_RST_ACKNOWLEDGEMENT, GetParam()));
275 }
276
277 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
278 QuicPacketSequenceNumber sequence_number) {
279 return maker_.MakeAckAndRstPacket(
280 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
281 2, 1, !kIncludeCongestionFeedback);
282 }
283
284 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
285 QuicPacketSequenceNumber sequence_number,
286 QuicPacketSequenceNumber largest_received,
287 QuicPacketSequenceNumber least_unacked) {
288 return maker_.MakeAckPacket(sequence_number, largest_received,
289 least_unacked, !kIncludeCongestionFeedback);
290 }
291
292 BoundNetLog net_log_;
293 bool use_closing_stream_;
294 MockSendAlgorithm* send_algorithm_;
295 scoped_refptr<TestTaskRunner> runner_;
296 scoped_ptr<MockWrite[]> mock_writes_;
297 MockClock clock_;
298 TestQuicConnection* connection_;
299 scoped_ptr<QuicConnectionHelper> helper_;
300 testing::StrictMock<MockConnectionVisitor> visitor_;
301 scoped_ptr<QuicHttpStream> stream_;
302 TransportSecurityState transport_security_state_;
303 scoped_ptr<QuicClientSession> session_;
304 QuicCryptoClientConfig crypto_config_;
305 TestCompletionCallback callback_;
306 HttpRequestInfo request_;
307 HttpRequestHeaders headers_;
308 HttpResponseInfo response_;
309 scoped_refptr<IOBufferWithSize> read_buffer_;
310 SpdyHeaderBlock request_headers_;
311 SpdyHeaderBlock response_headers_;
312 std::string request_data_;
313 std::string response_data_;
314
315 private:
316 const QuicConnectionId connection_id_;
317 const QuicStreamId stream_id_;
318 QuicTestPacketMaker maker_;
319 IPEndPoint self_addr_;
320 IPEndPoint peer_addr_;
321 MockRandom random_generator_;
322 MockCryptoClientStreamFactory crypto_client_stream_factory_;
323 scoped_ptr<StaticSocketDataProvider> socket_data_;
324 std::vector<PacketToWrite> writes_;
325 };
326
327 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest,
328 ::testing::ValuesIn(QuicSupportedVersions()));
329
330 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) {
331 Initialize();
332 EXPECT_EQ(nullptr, stream_->RenewStreamForAuth());
333 }
334
335 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) {
336 Initialize();
337 EXPECT_TRUE(stream_->CanFindEndOfResponse());
338 }
339
340 TEST_P(QuicHttpStreamTest, IsConnectionReusable) {
341 Initialize();
342 EXPECT_FALSE(stream_->IsConnectionReusable());
343 }
344
345 TEST_P(QuicHttpStreamTest, GetRequest) {
346 SetRequest("GET", "/", DEFAULT_PRIORITY);
347 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
348 Initialize();
349
350 request_.method = "GET";
351 request_.url = GURL("http://www.google.com/");
352
353 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
354 net_log_, callback_.callback()));
355 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
356 callback_.callback()));
357
358 // Ack the request.
359 ProcessPacket(ConstructAckPacket(1, 0, 0));
360
361 EXPECT_EQ(ERR_IO_PENDING,
362 stream_->ReadResponseHeaders(callback_.callback()));
363
364 SetResponse("404 Not Found", std::string());
365 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
366
367 // Now that the headers have been processed, the callback will return.
368 EXPECT_EQ(OK, callback_.WaitForResult());
369 ASSERT_TRUE(response_.headers.get());
370 EXPECT_EQ(404, response_.headers->response_code());
371 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
372 EXPECT_FALSE(response_.response_time.is_null());
373 EXPECT_FALSE(response_.request_time.is_null());
374
375 // There is no body, so this should return immediately.
376 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
377 read_buffer_->size(),
378 callback_.callback()));
379 EXPECT_TRUE(stream_->IsResponseBodyComplete());
380 EXPECT_TRUE(AtEof());
381 }
382
383 // Regression test for http://crbug.com/288128
384 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) {
385 SetRequest("GET", "/", DEFAULT_PRIORITY);
386 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
387 Initialize();
388
389 request_.method = "GET";
390 request_.url = GURL("http://www.google.com/");
391
392 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
393 net_log_, callback_.callback()));
394 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
395 callback_.callback()));
396
397 // Ack the request.
398 ProcessPacket(ConstructAckPacket(1, 0, 0));
399
400 EXPECT_EQ(ERR_IO_PENDING,
401 stream_->ReadResponseHeaders(callback_.callback()));
402
403 SpdyHeaderBlock headers;
404 headers[":status"] = "200 OK";
405 headers[":version"] = "HTTP/1.1";
406 headers["content-type"] = "text/plain";
407 headers["big6"] = std::string(10000, 'x'); // Lots of x's.
408
409 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers);
410 EXPECT_LT(4096u, response.length());
411 stream_->OnDataReceived(response.data(), response.length());
412 stream_->OnClose(QUIC_NO_ERROR);
413
414 // Now that the headers have been processed, the callback will return.
415 EXPECT_EQ(OK, callback_.WaitForResult());
416 ASSERT_TRUE(response_.headers.get());
417 EXPECT_EQ(200, response_.headers->response_code());
418 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
419
420 // There is no body, so this should return immediately.
421 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(),
422 read_buffer_->size(),
423 callback_.callback()));
424 EXPECT_TRUE(stream_->IsResponseBodyComplete());
425 EXPECT_TRUE(AtEof());
426 }
427
428 // Regression test for http://crbug.com/409101
429 TEST_P(QuicHttpStreamTest, SessionClosedBeforeSendRequest) {
430 SetRequest("GET", "/", DEFAULT_PRIORITY);
431 Initialize();
432
433 request_.method = "GET";
434 request_.url = GURL("http://www.google.com/");
435
436 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
437 net_log_, callback_.callback()));
438
439 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
440
441 EXPECT_EQ(ERR_CONNECTION_CLOSED,
442 stream_->SendRequest(headers_, &response_,
443 callback_.callback()));
444 }
445
446 // Regression test for http://crbug.com/409871
447 TEST_P(QuicHttpStreamTest, SessionClosedBeforeReadResponseHeaders) {
448 SetRequest("GET", "/", DEFAULT_PRIORITY);
449 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
450 Initialize();
451
452 request_.method = "GET";
453 request_.url = GURL("http://www.google.com/");
454
455 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
456 net_log_, callback_.callback()));
457
458 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
459 callback_.callback()));
460
461 session_->connection()->CloseConnection(QUIC_NO_ERROR, true);
462
463 EXPECT_NE(OK, stream_->ReadResponseHeaders(callback_.callback()));
464 }
465
466 TEST_P(QuicHttpStreamTest, SendPostRequest) {
467 SetRequest("POST", "/", DEFAULT_PRIORITY);
468 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
469 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
470 AddWrite(ConstructAckPacket(3, 3, 1));
471
472 Initialize();
473
474 ScopedVector<UploadElementReader> element_readers;
475 element_readers.push_back(
476 new UploadBytesElementReader(kUploadData, strlen(kUploadData)));
477 ElementsUploadDataStream upload_data_stream(element_readers.Pass(), 0);
478 request_.method = "POST";
479 request_.url = GURL("http://www.google.com/");
480 request_.upload_data_stream = &upload_data_stream;
481 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback()));
482
483 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
484 net_log_, callback_.callback()));
485 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
486 callback_.callback()));
487
488 // Ack both packets in the request.
489 ProcessPacket(ConstructAckPacket(1, 0, 0));
490
491 // Send the response headers (but not the body).
492 SetResponse("200 OK", std::string());
493 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
494
495 // Since the headers have already arrived, this should return immediately.
496 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
497 ASSERT_TRUE(response_.headers.get());
498 EXPECT_EQ(200, response_.headers->response_code());
499 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
500
501 // Send the response body.
502 const char kResponseBody[] = "Hello world!";
503 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody));
504 // Since the body has already arrived, this should return immediately.
505 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)),
506 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
507 callback_.callback()));
508
509 EXPECT_TRUE(stream_->IsResponseBodyComplete());
510 EXPECT_TRUE(AtEof());
511 }
512
513 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) {
514 SetRequest("POST", "/", DEFAULT_PRIORITY);
515 size_t chunk_size = strlen(kUploadData);
516 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
517 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
518 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size,
519 kUploadData));
520 AddWrite(ConstructAckPacket(4, 3, 1));
521 Initialize();
522
523 ChunkedUploadDataStream upload_data_stream(0);
524 upload_data_stream.AppendData(kUploadData, chunk_size, false);
525
526 request_.method = "POST";
527 request_.url = GURL("http://www.google.com/");
528 request_.upload_data_stream = &upload_data_stream;
529 ASSERT_EQ(OK, request_.upload_data_stream->Init(
530 TestCompletionCallback().callback()));
531
532 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
533 net_log_, callback_.callback()));
534 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
535 callback_.callback()));
536
537 upload_data_stream.AppendData(kUploadData, chunk_size, true);
538
539 // Ack both packets in the request.
540 ProcessPacket(ConstructAckPacket(1, 0, 0));
541
542 // Send the response headers (but not the body).
543 SetResponse("200 OK", std::string());
544 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
545
546 // Since the headers have already arrived, this should return immediately.
547 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
548 ASSERT_TRUE(response_.headers.get());
549 EXPECT_EQ(200, response_.headers->response_code());
550 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
551
552 // Send the response body.
553 const char kResponseBody[] = "Hello world!";
554 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
555 kResponseBody));
556
557 // Since the body has already arrived, this should return immediately.
558 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
559 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
560 callback_.callback()));
561
562 EXPECT_TRUE(stream_->IsResponseBodyComplete());
563 EXPECT_TRUE(AtEof());
564 }
565
566 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithFinalEmptyDataPacket) {
567 SetRequest("POST", "/", DEFAULT_PRIORITY);
568 size_t chunk_size = strlen(kUploadData);
569 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
570 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData));
571 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, ""));
572 AddWrite(ConstructAckPacket(4, 3, 1));
573 Initialize();
574
575 ChunkedUploadDataStream upload_data_stream(0);
576 upload_data_stream.AppendData(kUploadData, chunk_size, false);
577
578 request_.method = "POST";
579 request_.url = GURL("http://www.google.com/");
580 request_.upload_data_stream = &upload_data_stream;
581 ASSERT_EQ(OK, request_.upload_data_stream->Init(
582 TestCompletionCallback().callback()));
583
584 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
585 net_log_, callback_.callback()));
586 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
587 callback_.callback()));
588
589 upload_data_stream.AppendData(nullptr, 0, true);
590
591 ProcessPacket(ConstructAckPacket(1, 0, 0));
592
593 // Send the response headers (but not the body).
594 SetResponse("200 OK", std::string());
595 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
596
597 // Since the headers have already arrived, this should return immediately.
598 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
599 ASSERT_TRUE(response_.headers.get());
600 EXPECT_EQ(200, response_.headers->response_code());
601 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
602
603 // Send the response body.
604 const char kResponseBody[] = "Hello world!";
605 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
606 kResponseBody));
607
608 // Since the body has already arrived, this should return immediately.
609 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
610 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
611 callback_.callback()));
612
613 EXPECT_TRUE(stream_->IsResponseBodyComplete());
614 EXPECT_TRUE(AtEof());
615 }
616
617 TEST_P(QuicHttpStreamTest, SendChunkedPostRequestWithOneEmptyDataPacket) {
618 SetRequest("POST", "/", DEFAULT_PRIORITY);
619 AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY));
620 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, ""));
621 AddWrite(ConstructAckPacket(3, 3, 1));
622 Initialize();
623
624 ChunkedUploadDataStream upload_data_stream(0);
625
626 request_.method = "POST";
627 request_.url = GURL("http://www.google.com/");
628 request_.upload_data_stream = &upload_data_stream;
629 ASSERT_EQ(OK, request_.upload_data_stream->Init(
630 TestCompletionCallback().callback()));
631
632 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
633 net_log_, callback_.callback()));
634 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_,
635 callback_.callback()));
636
637 upload_data_stream.AppendData(nullptr, 0, true);
638
639 ProcessPacket(ConstructAckPacket(1, 0, 0));
640
641 // Send the response headers (but not the body).
642 SetResponse("200 OK", std::string());
643 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin));
644
645 // Since the headers have already arrived, this should return immediately.
646 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback()));
647 ASSERT_TRUE(response_.headers.get());
648 EXPECT_EQ(200, response_.headers->response_code());
649 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain"));
650
651 // Send the response body.
652 const char kResponseBody[] = "Hello world!";
653 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(),
654 kResponseBody));
655
656 // Since the body has already arrived, this should return immediately.
657 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)),
658 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(),
659 callback_.callback()));
660
661 EXPECT_TRUE(stream_->IsResponseBodyComplete());
662 EXPECT_TRUE(AtEof());
663 }
664
665 TEST_P(QuicHttpStreamTest, DestroyedEarly) {
666 SetRequest("GET", "/", DEFAULT_PRIORITY);
667 AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY));
668 AddWrite(ConstructAckAndRstStreamPacket(2));
669 use_closing_stream_ = true;
670 Initialize();
671
672 request_.method = "GET";
673 request_.url = GURL("http://www.google.com/");
674
675 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY,
676 net_log_, callback_.callback()));
677 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
678 callback_.callback()));
679
680 // Ack the request.
681 ProcessPacket(ConstructAckPacket(1, 0, 0));
682 EXPECT_EQ(ERR_IO_PENDING,
683 stream_->ReadResponseHeaders(callback_.callback()));
684
685 // Send the response with a body.
686 SetResponse("404 OK", "hello world!");
687 // In the course of processing this packet, the QuicHttpStream close itself.
688 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
689
690 EXPECT_TRUE(AtEof());
691 }
692
693 TEST_P(QuicHttpStreamTest, Priority) {
694 SetRequest("GET", "/", MEDIUM);
695 AddWrite(ConstructRequestHeadersPacket(1, kFin, MEDIUM));
696 AddWrite(ConstructAckAndRstStreamPacket(2));
697 use_closing_stream_ = true;
698 Initialize();
699
700 request_.method = "GET";
701 request_.url = GURL("http://www.google.com/");
702
703 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
704 net_log_, callback_.callback()));
705
706 // Check that priority is highest.
707 QuicReliableClientStream* reliable_stream =
708 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
709 DCHECK(reliable_stream);
710 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
711 reliable_stream->EffectivePriority());
712
713 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_,
714 callback_.callback()));
715
716 // Check that priority has now dropped back to MEDIUM.
717 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority(
718 reliable_stream->EffectivePriority()));
719
720 // Ack the request.
721 ProcessPacket(ConstructAckPacket(1, 0, 0));
722 EXPECT_EQ(ERR_IO_PENDING,
723 stream_->ReadResponseHeaders(callback_.callback()));
724
725 // Send the response with a body.
726 SetResponse("404 OK", "hello world!");
727 // In the course of processing this packet, the QuicHttpStream close itself.
728 ProcessPacket(ConstructResponseHeadersPacket(2, kFin));
729
730 EXPECT_TRUE(AtEof());
731 }
732
733 // Regression test for http://crbug.com/294870
734 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) {
735 SetRequest("GET", "/", MEDIUM);
736 use_closing_stream_ = true;
737
738 AddWrite(ConstructRstStreamPacket(1));
739
740 Initialize();
741
742 request_.method = "GET";
743 request_.url = GURL("http://www.google.com/");
744
745 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM,
746 net_log_, callback_.callback()));
747
748 // Check that priority is highest.
749 QuicReliableClientStream* reliable_stream =
750 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get());
751 DCHECK(reliable_stream);
752 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate();
753 DCHECK(delegate);
754 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
755 reliable_stream->EffectivePriority());
756
757 // Set Delegate to nullptr and make sure EffectivePriority returns highest
758 // priority.
759 reliable_stream->SetDelegate(nullptr);
760 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority,
761 reliable_stream->EffectivePriority());
762 reliable_stream->SetDelegate(delegate);
763 }
764
765 } // namespace test
766 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/quic_http_stream.cc ('k') | net/quic/quic_http_utils.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698