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/crypto/quic_server_info.h" 20 #include "net/quic/quic_client_session.h" 21 #include "net/quic/quic_connection.h" 22 #include "net/quic/quic_connection_helper.h" 23 #include "net/quic/quic_default_packet_writer.h" 24 #include "net/quic/quic_http_utils.h" 25 #include "net/quic/quic_reliable_client_stream.h" 26 #include "net/quic/quic_write_blocked_list.h" 27 #include "net/quic/spdy_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 "net/spdy/spdy_frame_builder.h" 37 #include "net/spdy/spdy_framer.h" 38 #include "net/spdy/spdy_http_utils.h" 39 #include "net/spdy/spdy_protocol.h" 40 #include "testing/gmock/include/gmock/gmock.h" 41 #include "testing/gtest/include/gtest/gtest.h" 42 43 using testing::_; 44 using testing::AnyNumber; 45 using testing::Return; 46 47 namespace net { 48 namespace test { 49 namespace { 50 51 const char kUploadData[] = "hello world!"; 52 const char kServerHostname[] = "www.google.com"; 53 const uint16 kServerPort = 80; 54 55 class TestQuicConnection : public QuicConnection { 56 public: 57 TestQuicConnection(const QuicVersionVector& versions, 58 QuicConnectionId connection_id, 59 IPEndPoint address, 60 QuicConnectionHelper* helper, 61 QuicPacketWriter* writer) 62 : QuicConnection(connection_id, address, helper, writer, false, 63 versions) { 64 } 65 66 void SetSendAlgorithm(SendAlgorithmInterface* send_algorithm) { 67 QuicConnectionPeer::SetSendAlgorithm(this, send_algorithm); 68 } 69 70 void SetReceiveAlgorithm(ReceiveAlgorithmInterface* receive_algorithm) { 71 QuicConnectionPeer::SetReceiveAlgorithm(this, receive_algorithm); 72 } 73 }; 74 75 class TestReceiveAlgorithm : public ReceiveAlgorithmInterface { 76 public: 77 virtual bool GenerateCongestionFeedback( 78 QuicCongestionFeedbackFrame* /*congestion_feedback*/) { 79 return false; 80 } 81 82 MOCK_METHOD3(RecordIncomingPacket, 83 void(QuicByteCount, QuicPacketSequenceNumber, QuicTime)); 84 }; 85 86 // Subclass of QuicHttpStream that closes itself when the first piece of data 87 // is received. 88 class AutoClosingStream : public QuicHttpStream { 89 public: 90 explicit AutoClosingStream(const base::WeakPtr<QuicClientSession>& session) 91 : QuicHttpStream(session) { 92 } 93 94 virtual int OnDataReceived(const char* data, int length) OVERRIDE { 95 Close(false); 96 return OK; 97 } 98 }; 99 100 } // namespace 101 102 class QuicHttpStreamPeer { 103 public: 104 static QuicReliableClientStream* GetQuicReliableClientStream( 105 QuicHttpStream* stream) { 106 return stream->stream_; 107 } 108 }; 109 110 class QuicHttpStreamTest : public ::testing::TestWithParam<QuicVersion> { 111 protected: 112 static const bool kFin = true; 113 static const bool kIncludeVersion = true; 114 static const bool kIncludeCongestionFeedback = true; 115 116 // Holds a packet to be written to the wire, and the IO mode that should 117 // be used by the mock socket when performing the write. 118 struct PacketToWrite { 119 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) 120 : mode(mode), 121 packet(packet) { 122 } 123 IoMode mode; 124 QuicEncryptedPacket* packet; 125 }; 126 127 QuicHttpStreamTest() 128 : net_log_(BoundNetLog()), 129 use_closing_stream_(false), 130 read_buffer_(new IOBufferWithSize(4096)), 131 connection_id_(2), 132 stream_id_(kClientDataStreamId1), 133 maker_(GetParam(), connection_id_), 134 random_generator_(0) { 135 IPAddressNumber ip; 136 CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip)); 137 peer_addr_ = IPEndPoint(ip, 443); 138 self_addr_ = IPEndPoint(ip, 8435); 139 } 140 141 ~QuicHttpStreamTest() { 142 session_->CloseSessionOnError(ERR_ABORTED); 143 for (size_t i = 0; i < writes_.size(); i++) { 144 delete writes_[i].packet; 145 } 146 } 147 148 // Adds a packet to the list of expected writes. 149 void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) { 150 writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release())); 151 } 152 153 // Returns the packet to be written at position |pos|. 154 QuicEncryptedPacket* GetWrite(size_t pos) { 155 return writes_[pos].packet; 156 } 157 158 bool AtEof() { 159 return socket_data_->at_read_eof() && socket_data_->at_write_eof(); 160 } 161 162 void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) { 163 connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet); 164 } 165 166 // Configures the test fixture to use the list of expected writes. 167 void Initialize() { 168 mock_writes_.reset(new MockWrite[writes_.size()]); 169 for (size_t i = 0; i < writes_.size(); i++) { 170 mock_writes_[i] = MockWrite(writes_[i].mode, 171 writes_[i].packet->data(), 172 writes_[i].packet->length()); 173 }; 174 175 socket_data_.reset(new StaticSocketDataProvider(NULL, 0, mock_writes_.get(), 176 writes_.size())); 177 178 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), 179 net_log_.net_log()); 180 socket->Connect(peer_addr_); 181 runner_ = new TestTaskRunner(&clock_); 182 send_algorithm_ = new MockSendAlgorithm(); 183 receive_algorithm_ = new TestReceiveAlgorithm(); 184 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _)). 185 Times(AnyNumber()); 186 EXPECT_CALL(*send_algorithm_, 187 OnPacketSent(_, _, _, _, _)).WillRepeatedly(Return(true)); 188 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( 189 Return(QuicTime::Delta::Zero())); 190 EXPECT_CALL(*send_algorithm_, GetCongestionWindow()).WillRepeatedly( 191 Return(kMaxPacketSize)); 192 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _)). 193 WillRepeatedly(Return(QuicTime::Delta::Zero())); 194 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( 195 Return(QuicBandwidth::Zero())); 196 EXPECT_CALL(*send_algorithm_, SetFromConfig(_, _)).Times(AnyNumber()); 197 helper_.reset(new QuicConnectionHelper(runner_.get(), &clock_, 198 &random_generator_)); 199 writer_.reset(new QuicDefaultPacketWriter(socket)); 200 connection_ = new TestQuicConnection(SupportedVersions(GetParam()), 201 connection_id_, peer_addr_, 202 helper_.get(), writer_.get()); 203 connection_->set_visitor(&visitor_); 204 connection_->SetSendAlgorithm(send_algorithm_); 205 connection_->SetReceiveAlgorithm(receive_algorithm_); 206 crypto_config_.SetDefaults(); 207 session_.reset( 208 new QuicClientSession(connection_, 209 scoped_ptr<DatagramClientSocket>(socket), 210 writer_.Pass(), NULL, 211 &crypto_client_stream_factory_, 212 make_scoped_ptr((QuicServerInfo*)NULL), 213 QuicServerId(kServerHostname, kServerPort, 214 false, PRIVACY_MODE_DISABLED), 215 DefaultQuicConfig(), &crypto_config_, 216 base::MessageLoop::current()-> 217 message_loop_proxy().get(), 218 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 clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20)); 225 } 226 227 void SetRequest(const std::string& method, 228 const std::string& path, 229 RequestPriority priority) { 230 request_headers_ = maker_.GetRequestHeaders(method, "http", path); 231 } 232 233 void SetResponse(const std::string& status, const std::string& body) { 234 response_headers_ = maker_.GetResponseHeaders(status); 235 response_data_ = body; 236 } 237 238 scoped_ptr<QuicEncryptedPacket> ConstructDataPacket( 239 QuicPacketSequenceNumber sequence_number, 240 bool should_include_version, 241 bool fin, 242 QuicStreamOffset offset, 243 base::StringPiece data) { 244 return maker_.MakeDataPacket( 245 sequence_number, stream_id_, should_include_version, fin, offset, data); 246 } 247 248 scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket( 249 QuicPacketSequenceNumber sequence_number, 250 bool fin) { 251 return maker_.MakeRequestHeadersPacket( 252 sequence_number, stream_id_, kIncludeVersion, fin, request_headers_); 253 } 254 255 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket( 256 QuicPacketSequenceNumber sequence_number, 257 bool fin) { 258 return maker_.MakeResponseHeadersPacket( 259 sequence_number, stream_id_, !kIncludeVersion, fin, response_headers_); 260 } 261 262 scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket( 263 QuicPacketSequenceNumber sequence_number) { 264 return maker_.MakeRstPacket( 265 sequence_number, true, stream_id_, 266 AdjustErrorForVersion(QUIC_RST_FLOW_CONTROL_ACCOUNTING, GetParam())); 267 } 268 269 scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket( 270 QuicPacketSequenceNumber sequence_number) { 271 return maker_.MakeAckAndRstPacket( 272 sequence_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED, 273 2, 1, !kIncludeCongestionFeedback); 274 } 275 276 scoped_ptr<QuicEncryptedPacket> ConstructAckPacket( 277 QuicPacketSequenceNumber sequence_number, 278 QuicPacketSequenceNumber largest_received, 279 QuicPacketSequenceNumber least_unacked) { 280 return maker_.MakeAckPacket(sequence_number, largest_received, 281 least_unacked, !kIncludeCongestionFeedback); 282 } 283 284 BoundNetLog net_log_; 285 bool use_closing_stream_; 286 MockSendAlgorithm* send_algorithm_; 287 TestReceiveAlgorithm* receive_algorithm_; 288 scoped_refptr<TestTaskRunner> runner_; 289 scoped_ptr<MockWrite[]> mock_writes_; 290 MockClock clock_; 291 TestQuicConnection* connection_; 292 scoped_ptr<QuicConnectionHelper> helper_; 293 testing::StrictMock<MockConnectionVisitor> visitor_; 294 scoped_ptr<QuicHttpStream> stream_; 295 scoped_ptr<QuicDefaultPacketWriter> writer_; 296 scoped_ptr<QuicClientSession> session_; 297 QuicCryptoClientConfig crypto_config_; 298 TestCompletionCallback callback_; 299 HttpRequestInfo request_; 300 HttpRequestHeaders headers_; 301 HttpResponseInfo response_; 302 scoped_refptr<IOBufferWithSize> read_buffer_; 303 SpdyHeaderBlock request_headers_; 304 SpdyHeaderBlock response_headers_; 305 std::string request_data_; 306 std::string response_data_; 307 308 private: 309 const QuicConnectionId connection_id_; 310 const QuicStreamId stream_id_; 311 QuicTestPacketMaker maker_; 312 IPEndPoint self_addr_; 313 IPEndPoint peer_addr_; 314 MockRandom random_generator_; 315 MockCryptoClientStreamFactory crypto_client_stream_factory_; 316 scoped_ptr<StaticSocketDataProvider> socket_data_; 317 std::vector<PacketToWrite> writes_; 318 }; 319 320 INSTANTIATE_TEST_CASE_P(Version, QuicHttpStreamTest, 321 ::testing::ValuesIn(QuicSupportedVersions())); 322 323 TEST_P(QuicHttpStreamTest, RenewStreamForAuth) { 324 Initialize(); 325 EXPECT_EQ(NULL, stream_->RenewStreamForAuth()); 326 } 327 328 TEST_P(QuicHttpStreamTest, CanFindEndOfResponse) { 329 Initialize(); 330 EXPECT_TRUE(stream_->CanFindEndOfResponse()); 331 } 332 333 TEST_P(QuicHttpStreamTest, IsConnectionReusable) { 334 Initialize(); 335 EXPECT_FALSE(stream_->IsConnectionReusable()); 336 } 337 338 TEST_P(QuicHttpStreamTest, GetRequest) { 339 SetRequest("GET", "/", DEFAULT_PRIORITY); 340 AddWrite(ConstructRequestHeadersPacket(1, kFin)); 341 Initialize(); 342 343 request_.method = "GET"; 344 request_.url = GURL("http://www.google.com/"); 345 346 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 347 net_log_, callback_.callback())); 348 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 349 callback_.callback())); 350 351 // Ack the request. 352 ProcessPacket(ConstructAckPacket(1, 0, 0)); 353 354 EXPECT_EQ(ERR_IO_PENDING, 355 stream_->ReadResponseHeaders(callback_.callback())); 356 357 SetResponse("404 Not Found", std::string()); 358 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 359 360 // Now that the headers have been processed, the callback will return. 361 EXPECT_EQ(OK, callback_.WaitForResult()); 362 ASSERT_TRUE(response_.headers.get()); 363 EXPECT_EQ(404, response_.headers->response_code()); 364 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 365 EXPECT_FALSE(response_.response_time.is_null()); 366 EXPECT_FALSE(response_.request_time.is_null()); 367 368 // There is no body, so this should return immediately. 369 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), 370 read_buffer_->size(), 371 callback_.callback())); 372 EXPECT_TRUE(stream_->IsResponseBodyComplete()); 373 EXPECT_TRUE(AtEof()); 374 } 375 376 // Regression test for http://crbug.com/288128 377 TEST_P(QuicHttpStreamTest, GetRequestLargeResponse) { 378 SetRequest("GET", "/", DEFAULT_PRIORITY); 379 AddWrite(ConstructRequestHeadersPacket(1, kFin)); 380 Initialize(); 381 382 request_.method = "GET"; 383 request_.url = GURL("http://www.google.com/"); 384 385 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 386 net_log_, callback_.callback())); 387 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 388 callback_.callback())); 389 390 // Ack the request. 391 ProcessPacket(ConstructAckPacket(1, 0, 0)); 392 393 EXPECT_EQ(ERR_IO_PENDING, 394 stream_->ReadResponseHeaders(callback_.callback())); 395 396 SpdyHeaderBlock headers; 397 headers[":status"] = "200 OK"; 398 headers[":version"] = "HTTP/1.1"; 399 headers["content-type"] = "text/plain"; 400 headers["big6"] = std::string(10000, 'x'); // Lots of x's. 401 402 std::string response = SpdyUtils::SerializeUncompressedHeaders(headers); 403 EXPECT_LT(4096u, response.length()); 404 stream_->OnDataReceived(response.data(), response.length()); 405 stream_->OnClose(QUIC_NO_ERROR); 406 407 // Now that the headers have been processed, the callback will return. 408 EXPECT_EQ(OK, callback_.WaitForResult()); 409 ASSERT_TRUE(response_.headers.get()); 410 EXPECT_EQ(200, response_.headers->response_code()); 411 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 412 413 // There is no body, so this should return immediately. 414 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), 415 read_buffer_->size(), 416 callback_.callback())); 417 EXPECT_TRUE(stream_->IsResponseBodyComplete()); 418 EXPECT_TRUE(AtEof()); 419 } 420 421 TEST_P(QuicHttpStreamTest, SendPostRequest) { 422 SetRequest("POST", "/", DEFAULT_PRIORITY); 423 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 424 AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData)); 425 AddWrite(ConstructAckPacket(3, 3, 1)); 426 427 Initialize(); 428 429 ScopedVector<UploadElementReader> element_readers; 430 element_readers.push_back( 431 new UploadBytesElementReader(kUploadData, strlen(kUploadData))); 432 UploadDataStream upload_data_stream(element_readers.Pass(), 0); 433 request_.method = "POST"; 434 request_.url = GURL("http://www.google.com/"); 435 request_.upload_data_stream = &upload_data_stream; 436 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 437 438 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 439 net_log_, callback_.callback())); 440 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 441 callback_.callback())); 442 443 // Ack both packets in the request. 444 ProcessPacket(ConstructAckPacket(1, 0, 0)); 445 446 // Send the response headers (but not the body). 447 SetResponse("200 OK", std::string()); 448 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 449 450 // Since the headers have already arrived, this should return immediately. 451 EXPECT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 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 // Send the response body. 457 const char kResponseBody[] = "Hello world!"; 458 ProcessPacket(ConstructDataPacket(3, false, kFin, 0, kResponseBody)); 459 // Since the body has already arrived, this should return immediately. 460 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), 461 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 462 callback_.callback())); 463 464 EXPECT_TRUE(stream_->IsResponseBodyComplete()); 465 EXPECT_TRUE(AtEof()); 466 } 467 468 TEST_P(QuicHttpStreamTest, SendChunkedPostRequest) { 469 SetRequest("POST", "/", DEFAULT_PRIORITY); 470 size_t chunk_size = strlen(kUploadData); 471 AddWrite(ConstructRequestHeadersPacket(1, !kFin)); 472 AddWrite(ConstructDataPacket(2, kIncludeVersion, !kFin, 0, kUploadData)); 473 AddWrite(ConstructDataPacket(3, kIncludeVersion, kFin, chunk_size, 474 kUploadData)); 475 AddWrite(ConstructAckPacket(4, 3, 1)); 476 Initialize(); 477 478 UploadDataStream upload_data_stream(UploadDataStream::CHUNKED, 0); 479 upload_data_stream.AppendChunk(kUploadData, chunk_size, false); 480 481 request_.method = "POST"; 482 request_.url = GURL("http://www.google.com/"); 483 request_.upload_data_stream = &upload_data_stream; 484 ASSERT_EQ(OK, request_.upload_data_stream->Init(CompletionCallback())); 485 486 ASSERT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 487 net_log_, callback_.callback())); 488 ASSERT_EQ(ERR_IO_PENDING, stream_->SendRequest(headers_, &response_, 489 callback_.callback())); 490 491 upload_data_stream.AppendChunk(kUploadData, chunk_size, true); 492 493 // Ack both packets in the request. 494 ProcessPacket(ConstructAckPacket(1, 0, 0)); 495 496 // Send the response headers (but not the body). 497 SetResponse("200 OK", std::string()); 498 ProcessPacket(ConstructResponseHeadersPacket(2, !kFin)); 499 500 // Since the headers have already arrived, this should return immediately. 501 ASSERT_EQ(OK, stream_->ReadResponseHeaders(callback_.callback())); 502 ASSERT_TRUE(response_.headers.get()); 503 EXPECT_EQ(200, response_.headers->response_code()); 504 EXPECT_TRUE(response_.headers->HasHeaderValue("Content-Type", "text/plain")); 505 506 // Send the response body. 507 const char kResponseBody[] = "Hello world!"; 508 ProcessPacket(ConstructDataPacket(3, false, kFin, response_data_.length(), 509 kResponseBody)); 510 511 // Since the body has already arrived, this should return immediately. 512 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), 513 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), 514 callback_.callback())); 515 516 EXPECT_TRUE(stream_->IsResponseBodyComplete()); 517 EXPECT_TRUE(AtEof()); 518 } 519 520 TEST_P(QuicHttpStreamTest, DestroyedEarly) { 521 SetRequest("GET", "/", DEFAULT_PRIORITY); 522 AddWrite(ConstructRequestHeadersPacket(1, kFin)); 523 AddWrite(ConstructAckAndRstStreamPacket(2)); 524 use_closing_stream_ = true; 525 Initialize(); 526 527 request_.method = "GET"; 528 request_.url = GURL("http://www.google.com/"); 529 530 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, 531 net_log_, callback_.callback())); 532 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 533 callback_.callback())); 534 535 // Ack the request. 536 ProcessPacket(ConstructAckPacket(1, 0, 0)); 537 EXPECT_EQ(ERR_IO_PENDING, 538 stream_->ReadResponseHeaders(callback_.callback())); 539 540 // Send the response with a body. 541 SetResponse("404 OK", "hello world!"); 542 // In the course of processing this packet, the QuicHttpStream close itself. 543 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 544 545 EXPECT_TRUE(AtEof()); 546 } 547 548 TEST_P(QuicHttpStreamTest, Priority) { 549 SetRequest("GET", "/", MEDIUM); 550 AddWrite(ConstructRequestHeadersPacket(1, kFin)); 551 AddWrite(ConstructAckAndRstStreamPacket(2)); 552 use_closing_stream_ = true; 553 Initialize(); 554 555 request_.method = "GET"; 556 request_.url = GURL("http://www.google.com/"); 557 558 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, 559 net_log_, callback_.callback())); 560 561 // Check that priority is highest. 562 QuicReliableClientStream* reliable_stream = 563 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); 564 DCHECK(reliable_stream); 565 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 566 reliable_stream->EffectivePriority()); 567 568 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, 569 callback_.callback())); 570 571 // Check that priority has now dropped back to MEDIUM. 572 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( 573 reliable_stream->EffectivePriority())); 574 575 // Ack the request. 576 ProcessPacket(ConstructAckPacket(1, 0, 0)); 577 EXPECT_EQ(ERR_IO_PENDING, 578 stream_->ReadResponseHeaders(callback_.callback())); 579 580 // Send the response with a body. 581 SetResponse("404 OK", "hello world!"); 582 // In the course of processing this packet, the QuicHttpStream close itself. 583 ProcessPacket(ConstructResponseHeadersPacket(2, kFin)); 584 585 EXPECT_TRUE(AtEof()); 586 } 587 588 // Regression test for http://crbug.com/294870 589 TEST_P(QuicHttpStreamTest, CheckPriorityWithNoDelegate) { 590 SetRequest("GET", "/", MEDIUM); 591 use_closing_stream_ = true; 592 593 AddWrite(ConstructRstStreamPacket(1)); 594 595 Initialize(); 596 597 request_.method = "GET"; 598 request_.url = GURL("http://www.google.com/"); 599 600 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, 601 net_log_, callback_.callback())); 602 603 // Check that priority is highest. 604 QuicReliableClientStream* reliable_stream = 605 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); 606 DCHECK(reliable_stream); 607 QuicReliableClientStream::Delegate* delegate = reliable_stream->GetDelegate(); 608 DCHECK(delegate); 609 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 610 reliable_stream->EffectivePriority()); 611 612 // Set Delegate to NULL and make sure EffectivePriority returns highest 613 // priority. 614 reliable_stream->SetDelegate(NULL); 615 DCHECK_EQ(QuicWriteBlockedList::kHighestPriority, 616 reliable_stream->EffectivePriority()); 617 reliable_stream->SetDelegate(delegate); 618 } 619 620 } // namespace test 621 } // namespace net 622