| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/quic/quic_http_stream.h" | 5 #include "net/quic/quic_http_stream.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "net/base/net_errors.h" | 9 #include "net/base/net_errors.h" |
| 10 #include "net/base/test_completion_callback.h" | 10 #include "net/base/test_completion_callback.h" |
| 11 #include "net/base/upload_bytes_element_reader.h" | 11 #include "net/base/upload_bytes_element_reader.h" |
| 12 #include "net/base/upload_data_stream.h" | 12 #include "net/base/upload_data_stream.h" |
| 13 #include "net/http/http_response_headers.h" | 13 #include "net/http/http_response_headers.h" |
| 14 #include "net/quic/congestion_control/receive_algorithm_interface.h" | 14 #include "net/quic/congestion_control/receive_algorithm_interface.h" |
| 15 #include "net/quic/congestion_control/send_algorithm_interface.h" | 15 #include "net/quic/congestion_control/send_algorithm_interface.h" |
| 16 #include "net/quic/crypto/crypto_protocol.h" | 16 #include "net/quic/crypto/crypto_protocol.h" |
| 17 #include "net/quic/crypto/quic_decrypter.h" | 17 #include "net/quic/crypto/quic_decrypter.h" |
| 18 #include "net/quic/crypto/quic_encrypter.h" | 18 #include "net/quic/crypto/quic_encrypter.h" |
| 19 #include "net/quic/quic_client_session.h" | 19 #include "net/quic/quic_client_session.h" |
| 20 #include "net/quic/quic_connection.h" | 20 #include "net/quic/quic_connection.h" |
| 21 #include "net/quic/quic_connection_helper.h" | 21 #include "net/quic/quic_connection_helper.h" |
| 22 #include "net/quic/quic_http_utils.h" |
| 23 #include "net/quic/quic_reliable_client_stream.h" |
| 22 #include "net/quic/spdy_utils.h" | 24 #include "net/quic/spdy_utils.h" |
| 23 #include "net/quic/test_tools/mock_clock.h" | 25 #include "net/quic/test_tools/mock_clock.h" |
| 24 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" | 26 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h" |
| 25 #include "net/quic/test_tools/mock_random.h" | 27 #include "net/quic/test_tools/mock_random.h" |
| 26 #include "net/quic/test_tools/quic_connection_peer.h" | 28 #include "net/quic/test_tools/quic_connection_peer.h" |
| 27 #include "net/quic/test_tools/quic_test_utils.h" | 29 #include "net/quic/test_tools/quic_test_utils.h" |
| 28 #include "net/quic/test_tools/test_task_runner.h" | 30 #include "net/quic/test_tools/test_task_runner.h" |
| 29 #include "net/socket/socket_test_util.h" | 31 #include "net/socket/socket_test_util.h" |
| 30 #include "net/spdy/spdy_frame_builder.h" | 32 #include "net/spdy/spdy_frame_builder.h" |
| 31 #include "net/spdy/spdy_framer.h" | 33 #include "net/spdy/spdy_framer.h" |
| 32 #include "net/spdy/spdy_http_utils.h" | 34 #include "net/spdy/spdy_http_utils.h" |
| 33 #include "net/spdy/spdy_protocol.h" | 35 #include "net/spdy/spdy_protocol.h" |
| 36 #include "net/spdy/write_blocked_list.h" |
| 34 #include "testing/gmock/include/gmock/gmock.h" | 37 #include "testing/gmock/include/gmock/gmock.h" |
| 35 #include "testing/gtest/include/gtest/gtest.h" | 38 #include "testing/gtest/include/gtest/gtest.h" |
| 36 | 39 |
| 37 using testing::_; | 40 using testing::_; |
| 38 using testing::AnyNumber; | 41 using testing::AnyNumber; |
| 39 using testing::Return; | 42 using testing::Return; |
| 40 | 43 |
| 41 namespace net { | 44 namespace net { |
| 42 namespace test { | 45 namespace test { |
| 43 namespace { | 46 namespace { |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 } | 98 } |
| 96 | 99 |
| 97 virtual int OnDataReceived(const char* data, int length) OVERRIDE { | 100 virtual int OnDataReceived(const char* data, int length) OVERRIDE { |
| 98 Close(false); | 101 Close(false); |
| 99 return OK; | 102 return OK; |
| 100 } | 103 } |
| 101 }; | 104 }; |
| 102 | 105 |
| 103 } // namespace | 106 } // namespace |
| 104 | 107 |
| 108 class QuicHttpStreamPeer { |
| 109 public: |
| 110 static QuicReliableClientStream* GetQuicReliableClientStream( |
| 111 QuicHttpStream* stream) { |
| 112 return stream->stream_; |
| 113 } |
| 114 }; |
| 115 |
| 105 class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { | 116 class QuicHttpStreamTest : public ::testing::TestWithParam<bool> { |
| 106 protected: | 117 protected: |
| 107 const static bool kFin = true; | 118 const static bool kFin = true; |
| 108 // Holds a packet to be written to the wire, and the IO mode that should | 119 // Holds a packet to be written to the wire, and the IO mode that should |
| 109 // be used by the mock socket when performing the write. | 120 // be used by the mock socket when performing the write. |
| 110 struct PacketToWrite { | 121 struct PacketToWrite { |
| 111 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) | 122 PacketToWrite(IoMode mode, QuicEncryptedPacket* packet) |
| 112 : mode(mode), | 123 : mode(mode), |
| 113 packet(packet) { | 124 packet(packet) { |
| 114 } | 125 } |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 writes_.size())); | 181 writes_.size())); |
| 171 | 182 |
| 172 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), | 183 MockUDPClientSocket* socket = new MockUDPClientSocket(socket_data_.get(), |
| 173 net_log_.net_log()); | 184 net_log_.net_log()); |
| 174 socket->Connect(peer_addr_); | 185 socket->Connect(peer_addr_); |
| 175 runner_ = new TestTaskRunner(&clock_); | 186 runner_ = new TestTaskRunner(&clock_); |
| 176 send_algorithm_ = new MockSendAlgorithm(); | 187 send_algorithm_ = new MockSendAlgorithm(); |
| 177 receive_algorithm_ = new TestReceiveAlgorithm(NULL); | 188 receive_algorithm_ = new TestReceiveAlgorithm(NULL); |
| 178 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). | 189 EXPECT_CALL(*receive_algorithm_, RecordIncomingPacket(_, _, _, _)). |
| 179 Times(AnyNumber()); | 190 Times(AnyNumber()); |
| 180 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _)).Times(AnyNumber()); | 191 EXPECT_CALL(*send_algorithm_, SentPacket(_, _, _, _, _)).Times(AnyNumber()); |
| 181 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( | 192 EXPECT_CALL(*send_algorithm_, RetransmissionDelay()).WillRepeatedly( |
| 182 Return(QuicTime::Delta::Zero())); | 193 Return(QuicTime::Delta::Zero())); |
| 183 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). | 194 EXPECT_CALL(*send_algorithm_, TimeUntilSend(_, _, _, _)). |
| 184 WillRepeatedly(Return(QuicTime::Delta::Zero())); | 195 WillRepeatedly(Return(QuicTime::Delta::Zero())); |
| 185 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( | 196 EXPECT_CALL(*send_algorithm_, SmoothedRtt()).WillRepeatedly( |
| 186 Return(QuicTime::Delta::Zero())); | 197 Return(QuicTime::Delta::Zero())); |
| 187 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( | 198 EXPECT_CALL(*send_algorithm_, BandwidthEstimate()).WillRepeatedly( |
| 188 Return(QuicBandwidth::Zero())); | 199 Return(QuicBandwidth::Zero())); |
| 189 helper_ = new QuicConnectionHelper(runner_.get(), &clock_, | 200 helper_ = new QuicConnectionHelper(runner_.get(), &clock_, |
| 190 &random_generator_, socket); | 201 &random_generator_, socket); |
| 191 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_); | 202 connection_ = new TestQuicConnection(guid_, peer_addr_, helper_); |
| 192 connection_->set_visitor(&visitor_); | 203 connection_->set_visitor(&visitor_); |
| 193 connection_->SetSendAlgorithm(send_algorithm_); | 204 connection_->SetSendAlgorithm(send_algorithm_); |
| 194 connection_->SetReceiveAlgorithm(receive_algorithm_); | 205 connection_->SetReceiveAlgorithm(receive_algorithm_); |
| 195 crypto_config_.SetDefaults(); | 206 crypto_config_.SetDefaults(); |
| 196 session_.reset( | 207 session_.reset( |
| 197 new QuicClientSession(connection_, | 208 new QuicClientSession(connection_, |
| 198 scoped_ptr<DatagramClientSocket>(socket), NULL, | 209 scoped_ptr<DatagramClientSocket>(socket), NULL, |
| 199 &crypto_client_stream_factory_, | 210 &crypto_client_stream_factory_, |
| 200 "www.google.com", DefaultQuicConfig(), | 211 "www.google.com", DefaultQuicConfig(), |
| 201 &crypto_config_, NULL)); | 212 &crypto_config_, NULL)); |
| 202 session_->GetCryptoStream()->CryptoConnect(); | 213 session_->GetCryptoStream()->CryptoConnect(); |
| 203 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); | 214 EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed()); |
| 204 stream_.reset(use_closing_stream_ ? | 215 stream_.reset(use_closing_stream_ ? |
| 205 new AutoClosingStream(session_->GetWeakPtr()) : | 216 new AutoClosingStream(session_->GetWeakPtr()) : |
| 206 new QuicHttpStream(session_->GetWeakPtr())); | 217 new QuicHttpStream(session_->GetWeakPtr())); |
| 207 } | 218 } |
| 208 | 219 |
| 209 void SetRequestString(const std::string& method, const std::string& path) { | 220 void SetRequestString(const std::string& method, |
| 221 const std::string& path, |
| 222 RequestPriority priority) { |
| 210 SpdyHeaderBlock headers; | 223 SpdyHeaderBlock headers; |
| 211 headers[":method"] = method; | 224 headers[":method"] = method; |
| 212 headers[":host"] = "www.google.com"; | 225 headers[":host"] = "www.google.com"; |
| 213 headers[":path"] = path; | 226 headers[":path"] = path; |
| 214 headers[":scheme"] = "http"; | 227 headers[":scheme"] = "http"; |
| 215 headers[":version"] = "HTTP/1.1"; | 228 headers[":version"] = "HTTP/1.1"; |
| 216 request_data_ = SerializeHeaderBlock(headers, true); | 229 request_data_ = SerializeHeaderBlock(headers, true, priority); |
| 217 } | 230 } |
| 218 | 231 |
| 219 void SetResponseString(const std::string& status, const std::string& body) { | 232 void SetResponseString(const std::string& status, const std::string& body) { |
| 220 SpdyHeaderBlock headers; | 233 SpdyHeaderBlock headers; |
| 221 headers[":status"] = status; | 234 headers[":status"] = status; |
| 222 headers[":version"] = "HTTP/1.1"; | 235 headers[":version"] = "HTTP/1.1"; |
| 223 headers["content-type"] = "text/plain"; | 236 headers["content-type"] = "text/plain"; |
| 224 response_data_ = SerializeHeaderBlock(headers, false) + body; | 237 response_data_ = SerializeHeaderBlock(headers, false, DEFAULT_PRIORITY) + |
| 238 body; |
| 225 } | 239 } |
| 226 | 240 |
| 227 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, | 241 std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers, |
| 228 bool write_priority) { | 242 bool write_priority, |
| 243 RequestPriority priority) { |
| 229 QuicSpdyCompressor compressor; | 244 QuicSpdyCompressor compressor; |
| 230 if (framer_.version() >= QUIC_VERSION_9 && write_priority) { | 245 if (framer_.version() >= QUIC_VERSION_9 && write_priority) { |
| 231 return compressor.CompressHeadersWithPriority(0, headers); | 246 return compressor.CompressHeadersWithPriority( |
| 247 ConvertRequestPriorityToQuicPriority(priority), headers); |
| 232 } | 248 } |
| 233 return compressor.CompressHeaders(headers); | 249 return compressor.CompressHeaders(headers); |
| 234 } | 250 } |
| 235 | 251 |
| 236 // Returns a newly created packet to send kData on stream 3. | 252 // Returns a newly created packet to send kData on stream 3. |
| 237 QuicEncryptedPacket* ConstructDataPacket( | 253 QuicEncryptedPacket* ConstructDataPacket( |
| 238 QuicPacketSequenceNumber sequence_number, | 254 QuicPacketSequenceNumber sequence_number, |
| 239 bool should_include_version, | 255 bool should_include_version, |
| 240 bool fin, | 256 bool fin, |
| 241 QuicStreamOffset offset, | 257 QuicStreamOffset offset, |
| 242 base::StringPiece data) { | 258 base::StringPiece data) { |
| 243 InitializeHeader(sequence_number, should_include_version); | 259 InitializeHeader(sequence_number, should_include_version); |
| 244 QuicStreamFrame frame(3, fin, offset, data); | 260 QuicStreamFrame frame(3, fin, offset, data); |
| 245 return ConstructPacket(header_, QuicFrame(&frame)); | 261 return ConstructPacket(header_, QuicFrame(&frame)); |
| 246 } | 262 } |
| 247 | 263 |
| 248 // Returns a newly created packet to RST_STREAM stream 3. | 264 // Returns a newly created packet to RST_STREAM stream 3. |
| 249 QuicEncryptedPacket* ConstructRstStreamPacket( | 265 QuicEncryptedPacket* ConstructRstStreamPacket( |
| 250 QuicPacketSequenceNumber sequence_number) { | 266 QuicPacketSequenceNumber sequence_number) { |
| 251 InitializeHeader(sequence_number, false); | 267 InitializeHeader(sequence_number, false); |
| 252 QuicRstStreamFrame frame(3, QUIC_SERVER_ERROR_PROCESSING_STREAM); | 268 QuicRstStreamFrame frame(3, QUIC_ERROR_PROCESSING_STREAM); |
| 253 return ConstructPacket(header_, QuicFrame(&frame)); | 269 return ConstructPacket(header_, QuicFrame(&frame)); |
| 254 } | 270 } |
| 255 | 271 |
| 256 // Returns a newly created packet to send ack data. | 272 // Returns a newly created packet to send ack data. |
| 257 QuicEncryptedPacket* ConstructAckPacket( | 273 QuicEncryptedPacket* ConstructAckPacket( |
| 258 QuicPacketSequenceNumber sequence_number, | 274 QuicPacketSequenceNumber sequence_number, |
| 259 QuicPacketSequenceNumber largest_received, | 275 QuicPacketSequenceNumber largest_received, |
| 260 QuicPacketSequenceNumber least_unacked) { | 276 QuicPacketSequenceNumber least_unacked) { |
| 261 InitializeHeader(sequence_number, false); | 277 InitializeHeader(sequence_number, false); |
| 262 | 278 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 343 Initialize(); | 359 Initialize(); |
| 344 EXPECT_TRUE(stream_->CanFindEndOfResponse()); | 360 EXPECT_TRUE(stream_->CanFindEndOfResponse()); |
| 345 } | 361 } |
| 346 | 362 |
| 347 TEST_F(QuicHttpStreamTest, IsConnectionReusable) { | 363 TEST_F(QuicHttpStreamTest, IsConnectionReusable) { |
| 348 Initialize(); | 364 Initialize(); |
| 349 EXPECT_FALSE(stream_->IsConnectionReusable()); | 365 EXPECT_FALSE(stream_->IsConnectionReusable()); |
| 350 } | 366 } |
| 351 | 367 |
| 352 TEST_F(QuicHttpStreamTest, GetRequest) { | 368 TEST_F(QuicHttpStreamTest, GetRequest) { |
| 353 SetRequestString("GET", "/"); | 369 SetRequestString("GET", "/", DEFAULT_PRIORITY); |
| 354 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 370 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, |
| 355 request_data_)); | 371 request_data_)); |
| 356 Initialize(); | 372 Initialize(); |
| 357 | 373 |
| 358 request_.method = "GET"; | 374 request_.method = "GET"; |
| 359 request_.url = GURL("http://www.google.com/"); | 375 request_.url = GURL("http://www.google.com/"); |
| 360 | 376 |
| 361 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 377 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 362 net_log_, callback_.callback())); | 378 net_log_, callback_.callback())); |
| 363 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 379 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| (...skipping 22 matching lines...) Expand all Loading... |
| 386 // There is no body, so this should return immediately. | 402 // There is no body, so this should return immediately. |
| 387 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 403 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
| 388 read_buffer_->size(), | 404 read_buffer_->size(), |
| 389 callback_.callback())); | 405 callback_.callback())); |
| 390 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 406 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 391 EXPECT_TRUE(AtEof()); | 407 EXPECT_TRUE(AtEof()); |
| 392 } | 408 } |
| 393 | 409 |
| 394 // Regression test for http://crbug.com/288128 | 410 // Regression test for http://crbug.com/288128 |
| 395 TEST_F(QuicHttpStreamTest, GetRequestLargeResponse) { | 411 TEST_F(QuicHttpStreamTest, GetRequestLargeResponse) { |
| 396 SetRequestString("GET", "/"); | 412 SetRequestString("GET", "/", DEFAULT_PRIORITY); |
| 397 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, | 413 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, |
| 398 request_data_)); | 414 request_data_)); |
| 399 Initialize(); | 415 Initialize(); |
| 400 | 416 |
| 401 request_.method = "GET"; | 417 request_.method = "GET"; |
| 402 request_.url = GURL("http://www.google.com/"); | 418 request_.url = GURL("http://www.google.com/"); |
| 403 | 419 |
| 404 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 420 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 405 net_log_, callback_.callback())); | 421 net_log_, callback_.callback())); |
| 406 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 422 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| (...skipping 26 matching lines...) Expand all Loading... |
| 433 | 449 |
| 434 // There is no body, so this should return immediately. | 450 // There is no body, so this should return immediately. |
| 435 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), | 451 EXPECT_EQ(0, stream_->ReadResponseBody(read_buffer_.get(), |
| 436 read_buffer_->size(), | 452 read_buffer_->size(), |
| 437 callback_.callback())); | 453 callback_.callback())); |
| 438 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 454 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 439 EXPECT_TRUE(AtEof()); | 455 EXPECT_TRUE(AtEof()); |
| 440 } | 456 } |
| 441 | 457 |
| 442 TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { | 458 TEST_F(QuicHttpStreamTest, GetRequestFullResponseInSinglePacket) { |
| 443 SetRequestString("GET", "/"); | 459 SetRequestString("GET", "/", DEFAULT_PRIORITY); |
| 444 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 460 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); |
| 445 Initialize(); | 461 Initialize(); |
| 446 | 462 |
| 447 request_.method = "GET"; | 463 request_.method = "GET"; |
| 448 request_.url = GURL("http://www.google.com/"); | 464 request_.url = GURL("http://www.google.com/"); |
| 449 | 465 |
| 450 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 466 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 451 net_log_, callback_.callback())); | 467 net_log_, callback_.callback())); |
| 452 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 468 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 453 callback_.callback())); | 469 callback_.callback())); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 475 // There is no body, so this should return immediately. | 491 // There is no body, so this should return immediately. |
| 476 // Since the body has already arrived, this should return immediately. | 492 // Since the body has already arrived, this should return immediately. |
| 477 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), | 493 EXPECT_EQ(12, stream_->ReadResponseBody(read_buffer_.get(), |
| 478 read_buffer_->size(), | 494 read_buffer_->size(), |
| 479 callback_.callback())); | 495 callback_.callback())); |
| 480 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 496 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 481 EXPECT_TRUE(AtEof()); | 497 EXPECT_TRUE(AtEof()); |
| 482 } | 498 } |
| 483 | 499 |
| 484 TEST_F(QuicHttpStreamTest, SendPostRequest) { | 500 TEST_F(QuicHttpStreamTest, SendPostRequest) { |
| 485 SetRequestString("POST", "/"); | 501 SetRequestString("POST", "/", DEFAULT_PRIORITY); |
| 486 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 502 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); |
| 487 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin, | 503 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, kFin, |
| 488 request_data_.length(), | 504 request_data_.length(), |
| 489 kUploadData)); | 505 kUploadData)); |
| 490 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1)); | 506 AddWrite(SYNCHRONOUS, ConstructAckPacket(3, 3, 1)); |
| 491 | 507 |
| 492 Initialize(); | 508 Initialize(); |
| 493 | 509 |
| 494 ScopedVector<UploadElementReader> element_readers; | 510 ScopedVector<UploadElementReader> element_readers; |
| 495 element_readers.push_back( | 511 element_readers.push_back( |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 532 // Since the body has already arrived, this should return immediately. | 548 // Since the body has already arrived, this should return immediately. |
| 533 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), | 549 EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), |
| 534 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 550 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
| 535 callback_.callback())); | 551 callback_.callback())); |
| 536 | 552 |
| 537 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 553 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 538 EXPECT_TRUE(AtEof()); | 554 EXPECT_TRUE(AtEof()); |
| 539 } | 555 } |
| 540 | 556 |
| 541 TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) { | 557 TEST_F(QuicHttpStreamTest, SendChunkedPostRequest) { |
| 542 SetRequestString("POST", "/"); | 558 SetRequestString("POST", "/", DEFAULT_PRIORITY); |
| 543 size_t chunk_size = strlen(kUploadData); | 559 size_t chunk_size = strlen(kUploadData); |
| 544 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); | 560 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, !kFin, 0, request_data_)); |
| 545 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin, | 561 AddWrite(SYNCHRONOUS, ConstructDataPacket(2, true, !kFin, |
| 546 request_data_.length(), | 562 request_data_.length(), |
| 547 kUploadData)); | 563 kUploadData)); |
| 548 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin, | 564 AddWrite(SYNCHRONOUS, ConstructDataPacket(3, true, kFin, |
| 549 request_data_.length() + chunk_size, | 565 request_data_.length() + chunk_size, |
| 550 kUploadData)); | 566 kUploadData)); |
| 551 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1)); | 567 AddWrite(SYNCHRONOUS, ConstructAckPacket(4, 3, 1)); |
| 552 | 568 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 594 // Since the body has already arrived, this should return immediately. | 610 // Since the body has already arrived, this should return immediately. |
| 595 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), | 611 ASSERT_EQ(static_cast<int>(strlen(kResponseBody)), |
| 596 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), | 612 stream_->ReadResponseBody(read_buffer_.get(), read_buffer_->size(), |
| 597 callback_.callback())); | 613 callback_.callback())); |
| 598 | 614 |
| 599 EXPECT_TRUE(stream_->IsResponseBodyComplete()); | 615 EXPECT_TRUE(stream_->IsResponseBodyComplete()); |
| 600 EXPECT_TRUE(AtEof()); | 616 EXPECT_TRUE(AtEof()); |
| 601 } | 617 } |
| 602 | 618 |
| 603 TEST_F(QuicHttpStreamTest, DestroyedEarly) { | 619 TEST_F(QuicHttpStreamTest, DestroyedEarly) { |
| 604 SetRequestString("GET", "/"); | 620 SetRequestString("GET", "/", DEFAULT_PRIORITY); |
| 605 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); | 621 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); |
| 606 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); | 622 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); |
| 607 use_closing_stream_ = true; | 623 use_closing_stream_ = true; |
| 608 Initialize(); | 624 Initialize(); |
| 609 | 625 |
| 610 request_.method = "GET"; | 626 request_.method = "GET"; |
| 611 request_.url = GURL("http://www.google.com/"); | 627 request_.url = GURL("http://www.google.com/"); |
| 612 | 628 |
| 613 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, | 629 EXPECT_EQ(OK, stream_->InitializeStream(&request_, DEFAULT_PRIORITY, |
| 614 net_log_, callback_.callback())); | 630 net_log_, callback_.callback())); |
| 615 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, | 631 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 616 callback_.callback())); | 632 callback_.callback())); |
| 617 EXPECT_EQ(&response_, stream_->GetResponseInfo()); | 633 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 618 | 634 |
| 619 // Ack the request. | 635 // Ack the request. |
| 620 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); | 636 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); |
| 621 ProcessPacket(*ack); | 637 ProcessPacket(*ack); |
| 638 EXPECT_EQ(ERR_IO_PENDING, |
| 639 stream_->ReadResponseHeaders(callback_.callback())); |
| 640 |
| 641 // Send the response with a body. |
| 642 SetResponseString("404 OK", "hello world!"); |
| 643 scoped_ptr<QuicEncryptedPacket> resp( |
| 644 ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 645 |
| 646 // In the course of processing this packet, the QuicHttpStream close itself. |
| 647 ProcessPacket(*resp); |
| 648 |
| 649 EXPECT_TRUE(AtEof()); |
| 650 } |
| 651 |
| 652 TEST_F(QuicHttpStreamTest, Priority) { |
| 653 SetRequestString("GET", "/", MEDIUM); |
| 654 AddWrite(SYNCHRONOUS, ConstructDataPacket(1, true, kFin, 0, request_data_)); |
| 655 AddWrite(SYNCHRONOUS, ConstructRstStreamPacket(2)); |
| 656 use_closing_stream_ = true; |
| 657 Initialize(); |
| 658 |
| 659 request_.method = "GET"; |
| 660 request_.url = GURL("http://www.google.com/"); |
| 661 |
| 662 EXPECT_EQ(OK, stream_->InitializeStream(&request_, MEDIUM, |
| 663 net_log_, callback_.callback())); |
| 664 |
| 665 // Check that priority is highest. |
| 666 QuicReliableClientStream* reliable_stream = |
| 667 QuicHttpStreamPeer::GetQuicReliableClientStream(stream_.get()); |
| 668 DCHECK(reliable_stream); |
| 669 DCHECK_EQ(static_cast<QuicPriority>(kHighestPriority), |
| 670 reliable_stream->EffectivePriority()); |
| 671 |
| 672 EXPECT_EQ(OK, stream_->SendRequest(headers_, &response_, |
| 673 callback_.callback())); |
| 674 EXPECT_EQ(&response_, stream_->GetResponseInfo()); |
| 675 |
| 676 // Check that priority has now dropped back to MEDIUM. |
| 677 DCHECK_EQ(MEDIUM, ConvertQuicPriorityToRequestPriority( |
| 678 reliable_stream->EffectivePriority())); |
| 679 |
| 680 // Ack the request. |
| 681 scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0, 0)); |
| 682 ProcessPacket(*ack); |
| 622 EXPECT_EQ(ERR_IO_PENDING, | 683 EXPECT_EQ(ERR_IO_PENDING, |
| 623 stream_->ReadResponseHeaders(callback_.callback())); | 684 stream_->ReadResponseHeaders(callback_.callback())); |
| 624 | 685 |
| 625 // Send the response with a body. | 686 // Send the response with a body. |
| 626 SetResponseString("404 OK", "hello world!"); | 687 SetResponseString("404 OK", "hello world!"); |
| 627 scoped_ptr<QuicEncryptedPacket> resp( | 688 scoped_ptr<QuicEncryptedPacket> resp( |
| 628 ConstructDataPacket(2, false, kFin, 0, response_data_)); | 689 ConstructDataPacket(2, false, kFin, 0, response_data_)); |
| 629 | 690 |
| 630 // In the course of processing this packet, the QuicHttpStream close itself. | 691 // In the course of processing this packet, the QuicHttpStream close itself. |
| 631 ProcessPacket(*resp); | 692 ProcessPacket(*resp); |
| 632 | 693 |
| 633 EXPECT_TRUE(AtEof()); | 694 EXPECT_TRUE(AtEof()); |
| 634 } | 695 } |
| 635 | 696 |
| 636 } // namespace test | 697 } // namespace test |
| 637 | 698 |
| 638 } // namespace net | 699 } // namespace net |
| OLD | NEW |