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