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