| Index: net/quic/bidirectional_stream_quic_impl_unittest.cc
|
| diff --git a/net/quic/bidirectional_stream_quic_impl_unittest.cc b/net/quic/bidirectional_stream_quic_impl_unittest.cc
|
| deleted file mode 100644
|
| index 3f38f5c5f845104b04818983e8fc54e08d20b649..0000000000000000000000000000000000000000
|
| --- a/net/quic/bidirectional_stream_quic_impl_unittest.cc
|
| +++ /dev/null
|
| @@ -1,1138 +0,0 @@
|
| -// Copyright 2016 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "net/quic/bidirectional_stream_quic_impl.h"
|
| -
|
| -#include <stdint.h>
|
| -#include <vector>
|
| -
|
| -#include "base/callback_helpers.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/run_loop.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/http/bidirectional_stream_request_info.h"
|
| -#include "net/http/transport_security_state.h"
|
| -#include "net/quic/crypto/crypto_protocol.h"
|
| -#include "net/quic/crypto/quic_decrypter.h"
|
| -#include "net/quic/crypto/quic_encrypter.h"
|
| -#include "net/quic/crypto/quic_server_info.h"
|
| -#include "net/quic/quic_chromium_client_session.h"
|
| -#include "net/quic/quic_chromium_client_stream.h"
|
| -#include "net/quic/quic_chromium_connection_helper.h"
|
| -#include "net/quic/quic_chromium_packet_reader.h"
|
| -#include "net/quic/quic_chromium_packet_writer.h"
|
| -#include "net/quic/quic_connection.h"
|
| -#include "net/quic/quic_http_utils.h"
|
| -#include "net/quic/spdy_utils.h"
|
| -#include "net/quic/test_tools/crypto_test_utils.h"
|
| -#include "net/quic/test_tools/mock_clock.h"
|
| -#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
|
| -#include "net/quic/test_tools/mock_random.h"
|
| -#include "net/quic/test_tools/quic_connection_peer.h"
|
| -#include "net/quic/test_tools/quic_test_packet_maker.h"
|
| -#include "net/quic/test_tools/quic_test_utils.h"
|
| -#include "net/quic/test_tools/test_task_runner.h"
|
| -#include "net/socket/socket_test_util.h"
|
| -#include "testing/gmock/include/gmock/gmock.h"
|
| -#include "testing/gtest/include/gtest/gtest.h"
|
| -
|
| -namespace net {
|
| -
|
| -namespace test {
|
| -
|
| -namespace {
|
| -
|
| -const char kUploadData[] = "Really nifty data!";
|
| -const char kDefaultServerHostName[] = "www.google.com";
|
| -const uint16_t kDefaultServerPort = 80;
|
| -// Size of the buffer to be allocated for each read.
|
| -const size_t kReadBufferSize = 4096;
|
| -
|
| -class TestDelegateBase : public BidirectionalStreamJob::Delegate {
|
| - public:
|
| - TestDelegateBase(IOBuffer* read_buf, int read_buf_len)
|
| - : TestDelegateBase(read_buf,
|
| - read_buf_len,
|
| - make_scoped_ptr(new base::Timer(false, false))) {}
|
| -
|
| - TestDelegateBase(IOBuffer* read_buf,
|
| - int read_buf_len,
|
| - scoped_ptr<base::Timer> timer)
|
| - : read_buf_(read_buf),
|
| - read_buf_len_(read_buf_len),
|
| - timer_(std::move(timer)),
|
| - loop_(nullptr),
|
| - error_(OK),
|
| - on_data_read_count_(0),
|
| - on_data_sent_count_(0),
|
| - not_expect_callback_(false) {
|
| - loop_.reset(new base::RunLoop);
|
| - }
|
| -
|
| - ~TestDelegateBase() override {}
|
| -
|
| - void OnHeadersSent() override {
|
| - CHECK(!not_expect_callback_);
|
| - loop_->Quit();
|
| - }
|
| -
|
| - void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
|
| - CHECK(!not_expect_callback_);
|
| -
|
| - response_headers_ = response_headers;
|
| - loop_->Quit();
|
| - }
|
| -
|
| - void OnDataRead(int bytes_read) override {
|
| - CHECK(!not_expect_callback_);
|
| - CHECK(!callback_.is_null());
|
| -
|
| - ++on_data_read_count_;
|
| - CHECK_GE(bytes_read, OK);
|
| - data_received_.append(read_buf_->data(), bytes_read);
|
| - base::ResetAndReturn(&callback_).Run(bytes_read);
|
| - }
|
| -
|
| - void OnDataSent() override {
|
| - CHECK(!not_expect_callback_);
|
| -
|
| - ++on_data_sent_count_;
|
| - loop_->Quit();
|
| - }
|
| -
|
| - void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
|
| - CHECK(!not_expect_callback_);
|
| -
|
| - trailers_ = trailers;
|
| - loop_->Quit();
|
| - }
|
| -
|
| - void OnFailed(int error) override {
|
| - CHECK(!not_expect_callback_);
|
| - CHECK_EQ(OK, error_);
|
| - CHECK_NE(OK, error);
|
| -
|
| - error_ = error;
|
| - loop_->Quit();
|
| - }
|
| -
|
| - void Start(const BidirectionalStreamRequestInfo* request_info,
|
| - const BoundNetLog& net_log,
|
| - const base::WeakPtr<QuicChromiumClientSession> session) {
|
| - stream_job_.reset(new BidirectionalStreamQuicImpl(session));
|
| - stream_job_->Start(request_info, net_log, this, nullptr);
|
| - }
|
| -
|
| - void SendData(IOBuffer* data, int length, bool end_of_stream) {
|
| - not_expect_callback_ = true;
|
| - stream_job_->SendData(data, length, end_of_stream);
|
| - not_expect_callback_ = false;
|
| - }
|
| -
|
| - // Waits until next Delegate callback.
|
| - void WaitUntilNextCallback() {
|
| - loop_->Run();
|
| - loop_.reset(new base::RunLoop);
|
| - }
|
| -
|
| - // Calls ReadData on the |stream_| and updates |data_received_|.
|
| - int ReadData(const CompletionCallback& callback) {
|
| - not_expect_callback_ = true;
|
| - int rv = stream_job_->ReadData(read_buf_.get(), read_buf_len_);
|
| - not_expect_callback_ = false;
|
| - if (rv > 0)
|
| - data_received_.append(read_buf_->data(), rv);
|
| - if (rv == ERR_IO_PENDING)
|
| - callback_ = callback;
|
| - return rv;
|
| - }
|
| -
|
| - // Cancels |stream_|.
|
| - void CancelStream() { stream_job_->Cancel(); }
|
| -
|
| - NextProto GetProtocol() const { return stream_job_->GetProtocol(); }
|
| -
|
| - int64_t GetTotalReceivedBytes() const {
|
| - return stream_job_->GetTotalReceivedBytes();
|
| - }
|
| -
|
| - int64_t GetTotalSentBytes() const { return stream_job_->GetTotalSentBytes(); }
|
| -
|
| - // Const getters for internal states.
|
| - const std::string& data_received() const { return data_received_; }
|
| - int error() const { return error_; }
|
| - const SpdyHeaderBlock& response_headers() const { return response_headers_; }
|
| - const SpdyHeaderBlock& trailers() const { return trailers_; }
|
| - int on_data_read_count() const { return on_data_read_count_; }
|
| - int on_data_sent_count() const { return on_data_sent_count_; }
|
| -
|
| - protected:
|
| - // Quits |loop_|.
|
| - void QuitLoop() { loop_->Quit(); }
|
| -
|
| - // Deletes |stream_|.
|
| - void DeleteStream() { stream_job_.reset(); }
|
| -
|
| - private:
|
| - scoped_ptr<BidirectionalStreamQuicImpl> stream_job_;
|
| - scoped_refptr<IOBuffer> read_buf_;
|
| - int read_buf_len_;
|
| - scoped_ptr<base::Timer> timer_;
|
| - std::string data_received_;
|
| - scoped_ptr<base::RunLoop> loop_;
|
| - SpdyHeaderBlock response_headers_;
|
| - SpdyHeaderBlock trailers_;
|
| - int error_;
|
| - int on_data_read_count_;
|
| - int on_data_sent_count_;
|
| - // This is to ensure that delegate callback is not invoked synchronously when
|
| - // calling into |stream_|.
|
| - bool not_expect_callback_;
|
| - CompletionCallback callback_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(TestDelegateBase);
|
| -};
|
| -
|
| -// A delegate that deletes the stream in a particular callback.
|
| -class DeleteStreamDelegate : public TestDelegateBase {
|
| - public:
|
| - // Specifies in which callback the stream can be deleted.
|
| - enum Phase {
|
| - ON_HEADERS_RECEIVED,
|
| - ON_DATA_READ,
|
| - ON_TRAILERS_RECEIVED,
|
| - ON_FAILED,
|
| - };
|
| -
|
| - DeleteStreamDelegate(IOBuffer* buf, int buf_len, Phase phase, bool do_cancel)
|
| - : TestDelegateBase(buf, buf_len), phase_(phase), do_cancel_(do_cancel) {}
|
| - ~DeleteStreamDelegate() override {}
|
| -
|
| - void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override {
|
| - if (phase_ == ON_HEADERS_RECEIVED) {
|
| - DeleteStream();
|
| - }
|
| - TestDelegateBase::OnHeadersReceived(response_headers);
|
| - }
|
| -
|
| - void OnDataSent() override { NOTREACHED(); }
|
| -
|
| - void OnDataRead(int bytes_read) override {
|
| - DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
|
| - if (phase_ == ON_DATA_READ)
|
| - DeleteStream();
|
| - TestDelegateBase::OnDataRead(bytes_read);
|
| - }
|
| -
|
| - void OnTrailersReceived(const SpdyHeaderBlock& trailers) override {
|
| - DCHECK_NE(ON_HEADERS_RECEIVED, phase_);
|
| - DCHECK_NE(ON_DATA_READ, phase_);
|
| - if (phase_ == ON_TRAILERS_RECEIVED)
|
| - DeleteStream();
|
| - TestDelegateBase::OnTrailersReceived(trailers);
|
| - }
|
| -
|
| - void OnFailed(int error) override {
|
| - DCHECK_EQ(ON_FAILED, phase_);
|
| - DeleteStream();
|
| - TestDelegateBase::OnFailed(error);
|
| - }
|
| -
|
| - private:
|
| - // Indicates in which callback the delegate should cancel or delete the
|
| - // stream.
|
| - Phase phase_;
|
| - // Indicates whether to cancel or delete the stream.
|
| - bool do_cancel_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(DeleteStreamDelegate);
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -class BidirectionalStreamQuicImplTest
|
| - : public ::testing::TestWithParam<QuicVersion> {
|
| - protected:
|
| - static const bool kFin = true;
|
| - static const bool kIncludeVersion = true;
|
| - static const bool kIncludeCongestionFeedback = true;
|
| -
|
| - // Holds a packet to be written to the wire, and the IO mode that should
|
| - // be used by the mock socket when performing the write.
|
| - struct PacketToWrite {
|
| - PacketToWrite(IoMode mode, QuicEncryptedPacket* packet)
|
| - : mode(mode), packet(packet) {}
|
| - PacketToWrite(IoMode mode, int rv) : mode(mode), packet(nullptr), rv(rv) {}
|
| - IoMode mode;
|
| - QuicEncryptedPacket* packet;
|
| - int rv;
|
| - };
|
| -
|
| - BidirectionalStreamQuicImplTest()
|
| - : net_log_(BoundNetLog()),
|
| - crypto_config_(CryptoTestUtils::ProofVerifierForTesting()),
|
| - read_buffer_(new IOBufferWithSize(4096)),
|
| - connection_id_(2),
|
| - stream_id_(kClientDataStreamId1),
|
| - maker_(GetParam(), connection_id_, &clock_, kDefaultServerHostName),
|
| - random_generator_(0) {
|
| - IPAddressNumber ip;
|
| - CHECK(ParseIPLiteralToNumber("192.0.2.33", &ip));
|
| - peer_addr_ = IPEndPoint(ip, 443);
|
| - self_addr_ = IPEndPoint(ip, 8435);
|
| - clock_.AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
|
| - }
|
| -
|
| - ~BidirectionalStreamQuicImplTest() {
|
| - session_->CloseSessionOnError(ERR_ABORTED, QUIC_INTERNAL_ERROR);
|
| - for (size_t i = 0; i < writes_.size(); i++) {
|
| - delete writes_[i].packet;
|
| - }
|
| - }
|
| -
|
| - void TearDown() override {
|
| - EXPECT_TRUE(socket_data_->AllReadDataConsumed());
|
| - EXPECT_TRUE(socket_data_->AllWriteDataConsumed());
|
| - }
|
| -
|
| - // Adds a packet to the list of expected writes.
|
| - void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
|
| - writes_.push_back(PacketToWrite(SYNCHRONOUS, packet.release()));
|
| - }
|
| -
|
| - void ProcessPacket(scoped_ptr<QuicEncryptedPacket> packet) {
|
| - connection_->ProcessUdpPacket(self_addr_, peer_addr_, *packet);
|
| - }
|
| -
|
| - // Configures the test fixture to use the list of expected writes.
|
| - void Initialize() {
|
| - mock_writes_.reset(new MockWrite[writes_.size()]);
|
| - for (size_t i = 0; i < writes_.size(); i++) {
|
| - if (writes_[i].packet == nullptr) {
|
| - mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].rv, i);
|
| - } else {
|
| - mock_writes_[i] = MockWrite(writes_[i].mode, writes_[i].packet->data(),
|
| - writes_[i].packet->length());
|
| - }
|
| - };
|
| -
|
| - socket_data_.reset(new StaticSocketDataProvider(
|
| - nullptr, 0, mock_writes_.get(), writes_.size()));
|
| -
|
| - MockUDPClientSocket* socket =
|
| - new MockUDPClientSocket(socket_data_.get(), net_log_.net_log());
|
| - socket->Connect(peer_addr_);
|
| - runner_ = new TestTaskRunner(&clock_);
|
| - helper_.reset(new QuicChromiumConnectionHelper(runner_.get(), &clock_,
|
| - &random_generator_));
|
| - connection_ = new QuicConnection(
|
| - connection_id_, peer_addr_, helper_.get(),
|
| - new QuicChromiumPacketWriter(socket), true /* owns_writer */,
|
| - Perspective::IS_CLIENT, SupportedVersions(GetParam()));
|
| -
|
| - session_.reset(new QuicChromiumClientSession(
|
| - connection_, scoped_ptr<DatagramClientSocket>(socket),
|
| - /*stream_factory=*/nullptr, &crypto_client_stream_factory_, &clock_,
|
| - &transport_security_state_, make_scoped_ptr((QuicServerInfo*)nullptr),
|
| - QuicServerId(kDefaultServerHostName, kDefaultServerPort,
|
| - PRIVACY_MODE_DISABLED),
|
| - kQuicYieldAfterPacketsRead,
|
| - QuicTime::Delta::FromMilliseconds(kQuicYieldAfterDurationMilliseconds),
|
| - /*cert_verify_flags=*/0, DefaultQuicConfig(), &crypto_config_,
|
| - "CONNECTION_UNKNOWN", base::TimeTicks::Now(), &push_promise_index_,
|
| - base::ThreadTaskRunnerHandle::Get().get(),
|
| - /*socket_performance_watcher=*/nullptr, nullptr));
|
| - session_->Initialize();
|
| - session_->GetCryptoStream()->CryptoConnect();
|
| - EXPECT_TRUE(session_->IsCryptoHandshakeConfirmed());
|
| - }
|
| -
|
| - void SetRequest(const std::string& method,
|
| - const std::string& path,
|
| - RequestPriority priority) {
|
| - request_headers_ = maker_.GetRequestHeaders(method, "http", path);
|
| - }
|
| -
|
| - SpdyHeaderBlock ConstructResponseHeaders(const std::string& response_code) {
|
| - return maker_.GetResponseHeaders(response_code);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
|
| - QuicPacketNumber packet_number,
|
| - bool should_include_version,
|
| - bool fin,
|
| - QuicStreamOffset offset,
|
| - base::StringPiece data) {
|
| - scoped_ptr<QuicEncryptedPacket> packet(maker_.MakeDataPacket(
|
| - packet_number, stream_id_, should_include_version, fin, offset, data));
|
| - DVLOG(2) << "packet(" << packet_number << "): " << std::endl
|
| - << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
|
| - return packet;
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
|
| - QuicPacketNumber packet_number,
|
| - bool fin,
|
| - RequestPriority request_priority,
|
| - size_t* spdy_headers_frame_length) {
|
| - SpdyPriority priority =
|
| - ConvertRequestPriorityToQuicPriority(request_priority);
|
| - return maker_.MakeRequestHeadersPacket(
|
| - packet_number, stream_id_, kIncludeVersion, fin, priority,
|
| - request_headers_, spdy_headers_frame_length);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
|
| - QuicPacketNumber packet_number,
|
| - bool fin,
|
| - const SpdyHeaderBlock& response_headers,
|
| - size_t* spdy_headers_frame_length,
|
| - QuicStreamOffset* offset) {
|
| - return maker_.MakeResponseHeadersPacket(
|
| - packet_number, stream_id_, !kIncludeVersion, fin, response_headers,
|
| - spdy_headers_frame_length, offset);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructResponseTrailersPacket(
|
| - QuicPacketNumber packet_number,
|
| - bool fin,
|
| - const SpdyHeaderBlock& trailers,
|
| - size_t* spdy_headers_frame_length,
|
| - QuicStreamOffset* offset) {
|
| - return maker_.MakeResponseHeadersPacket(packet_number, stream_id_,
|
| - !kIncludeVersion, fin, trailers,
|
| - spdy_headers_frame_length, offset);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructRstStreamPacket(
|
| - QuicPacketNumber packet_number) {
|
| - return ConstructRstStreamCancelledPacket(packet_number, 0);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructRstStreamCancelledPacket(
|
| - QuicPacketNumber packet_number,
|
| - size_t bytes_written) {
|
| - scoped_ptr<QuicEncryptedPacket> packet(
|
| - maker_.MakeRstPacket(packet_number, !kIncludeVersion, stream_id_,
|
| - QUIC_STREAM_CANCELLED, bytes_written));
|
| - DVLOG(2) << "packet(" << packet_number << "): " << std::endl
|
| - << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
|
| - return packet;
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructAckAndRstStreamPacket(
|
| - QuicPacketNumber packet_number,
|
| - QuicPacketNumber largest_received,
|
| - QuicPacketNumber ack_least_unacked,
|
| - QuicPacketNumber stop_least_unacked) {
|
| - return maker_.MakeAckAndRstPacket(
|
| - packet_number, !kIncludeVersion, stream_id_, QUIC_STREAM_CANCELLED,
|
| - largest_received, ack_least_unacked, stop_least_unacked,
|
| - !kIncludeCongestionFeedback);
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructAckAndDataPacket(
|
| - QuicPacketNumber packet_number,
|
| - bool should_include_version,
|
| - QuicPacketNumber largest_received,
|
| - QuicPacketNumber least_unacked,
|
| - bool fin,
|
| - QuicStreamOffset offset,
|
| - base::StringPiece data) {
|
| - scoped_ptr<QuicEncryptedPacket> packet(maker_.MakeAckAndDataPacket(
|
| - packet_number, should_include_version, stream_id_, largest_received,
|
| - least_unacked, fin, offset, data));
|
| - DVLOG(2) << "packet(" << packet_number << "): " << std::endl
|
| - << QuicUtils::StringToHexASCIIDump(packet->AsStringPiece());
|
| - return packet;
|
| - }
|
| -
|
| - scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
|
| - QuicPacketNumber packet_number,
|
| - QuicPacketNumber largest_received,
|
| - QuicPacketNumber least_unacked) {
|
| - return maker_.MakeAckPacket(packet_number, largest_received, least_unacked,
|
| - !kIncludeCongestionFeedback);
|
| - }
|
| -
|
| - const BoundNetLog& net_log() const { return net_log_; }
|
| -
|
| - QuicChromiumClientSession* session() const { return session_.get(); }
|
| -
|
| - private:
|
| - BoundNetLog net_log_;
|
| - scoped_refptr<TestTaskRunner> runner_;
|
| - scoped_ptr<MockWrite[]> mock_writes_;
|
| - MockClock clock_;
|
| - QuicConnection* connection_;
|
| - scoped_ptr<QuicChromiumConnectionHelper> helper_;
|
| - TransportSecurityState transport_security_state_;
|
| - scoped_ptr<QuicChromiumClientSession> session_;
|
| - QuicCryptoClientConfig crypto_config_;
|
| - HttpRequestHeaders headers_;
|
| - HttpResponseInfo response_;
|
| - scoped_refptr<IOBufferWithSize> read_buffer_;
|
| - SpdyHeaderBlock request_headers_;
|
| - const QuicConnectionId connection_id_;
|
| - const QuicStreamId stream_id_;
|
| - QuicTestPacketMaker maker_;
|
| - IPEndPoint self_addr_;
|
| - IPEndPoint peer_addr_;
|
| - MockRandom random_generator_;
|
| - MockCryptoClientStreamFactory crypto_client_stream_factory_;
|
| - scoped_ptr<StaticSocketDataProvider> socket_data_;
|
| - std::vector<PacketToWrite> writes_;
|
| - QuicClientPushPromiseIndex push_promise_index_;
|
| -};
|
| -
|
| -INSTANTIATE_TEST_CASE_P(Version,
|
| - BidirectionalStreamQuicImplTest,
|
| - ::testing::ValuesIn(QuicSupportedVersions()));
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, GetRequest) {
|
| - SetRequest("GET", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| -
|
| - AddWrite(ConstructAckPacket(2, 3, 1));
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "GET";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = true;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - size_t spdy_response_headers_frame_length;
|
| - QuicStreamOffset offset = 0;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| - const char kResponseBody[] = "Hello world!";
|
| - // Server sends data.
|
| - ProcessPacket(
|
| - ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
|
| - EXPECT_EQ(12, cb.WaitForResult());
|
| -
|
| - EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
|
| - TestCompletionCallback cb2;
|
| - EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb2.callback()));
|
| -
|
| - SpdyHeaderBlock trailers;
|
| - size_t spdy_trailers_frame_length;
|
| - trailers["foo"] = "bar";
|
| - trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
|
| - // Server sends trailers.
|
| - ProcessPacket(ConstructResponseTrailersPacket(
|
| - 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnTrailersReceived
|
| - EXPECT_EQ(OK, cb2.WaitForResult());
|
| - trailers.erase(kFinalOffsetHeaderKey);
|
| - EXPECT_EQ(trailers, delegate->trailers());
|
| -
|
| - EXPECT_EQ(OK, delegate->ReadData(cb2.callback()));
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(2, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(
|
| - static_cast<int64_t>(spdy_response_headers_frame_length +
|
| - strlen(kResponseBody) + spdy_trailers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, PostRequest) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructDataPacket(2, kIncludeVersion, kFin, 0, kUploadData));
|
| - AddWrite(ConstructAckPacket(3, 3, 1));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Send a DATA frame.
|
| - scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
|
| -
|
| - delegate->SendData(buf.get(), buf->size(), true);
|
| - delegate->WaitUntilNextCallback(); // OnDataSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| - size_t spdy_response_headers_frame_length;
|
| - QuicStreamOffset offset = 0;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| - const char kResponseBody[] = "Hello world!";
|
| - // Server sends data.
|
| - ProcessPacket(
|
| - ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
|
| -
|
| - EXPECT_EQ(static_cast<int>(strlen(kResponseBody)), cb.WaitForResult());
|
| -
|
| - size_t spdy_trailers_frame_length;
|
| - SpdyHeaderBlock trailers;
|
| - trailers["foo"] = "bar";
|
| - trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
|
| - // Server sends trailers.
|
| - ProcessPacket(ConstructResponseTrailersPacket(
|
| - 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnTrailersReceived
|
| - trailers.erase(kFinalOffsetHeaderKey);
|
| - EXPECT_EQ(trailers, delegate->trailers());
|
| - EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
|
| -
|
| - EXPECT_EQ(1, delegate->on_data_read_count());
|
| - EXPECT_EQ(1, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
|
| - strlen(kUploadData)),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(
|
| - static_cast<int64_t>(spdy_response_headers_frame_length +
|
| - strlen(kResponseBody) + spdy_trailers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, InterleaveReadDataAndSendData) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
|
| - kUploadData));
|
| - AddWrite(ConstructAckAndDataPacket(3, !kIncludeVersion, 3, 3, kFin,
|
| - strlen(kUploadData), kUploadData));
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - // Client sends a data packet.
|
| - scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
|
| -
|
| - delegate->SendData(buf.get(), buf->size(), false);
|
| - delegate->WaitUntilNextCallback(); // OnDataSent
|
| -
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - const char kResponseBody[] = "Hello world!";
|
| -
|
| - // Server sends a data packet.
|
| - ProcessPacket(ConstructAckAndDataPacket(3, !kIncludeVersion, 2, 1, !kFin, 0,
|
| - kResponseBody));
|
| -
|
| - EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
|
| - EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
|
| -
|
| - // Client sends a data packet.
|
| - delegate->SendData(buf.get(), buf->size(), true);
|
| - delegate->WaitUntilNextCallback(); // OnDataSent
|
| -
|
| - TestCompletionCallback cb2;
|
| - rv = delegate->ReadData(cb2.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - ProcessPacket(ConstructAckAndDataPacket(
|
| - 4, !kIncludeVersion, 3, 1, kFin, strlen(kResponseBody), kResponseBody));
|
| -
|
| - EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb2.WaitForResult());
|
| -
|
| - std::string expected_body(kResponseBody);
|
| - expected_body.append(kResponseBody);
|
| - EXPECT_EQ(expected_body, delegate->data_received());
|
| -
|
| - EXPECT_EQ(OK, delegate->ReadData(cb.callback()));
|
| - EXPECT_EQ(2, delegate->on_data_read_count());
|
| - EXPECT_EQ(2, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
|
| - 2 * strlen(kUploadData)),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length +
|
| - 2 * strlen(kResponseBody)),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterHeaders) {
|
| - SetRequest("GET", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "GET";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = true;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server sends a Rst.
|
| - ProcessPacket(ConstructRstStreamPacket(1));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnFailed
|
| - TestCompletionCallback cb;
|
| - EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(0, delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, ServerSendsRstAfterReadData) {
|
| - SetRequest("GET", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - // Why does QUIC ack Rst? Is this expected?
|
| - AddWrite(ConstructAckPacket(2, 3, 1));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "GET";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = true;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - size_t spdy_response_headers_frame_length;
|
| - QuicStreamOffset offset = 0;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| -
|
| - // Server sends a Rst.
|
| - ProcessPacket(ConstructRstStreamPacket(3));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnFailed
|
| -
|
| - EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->ReadData(cb.callback()));
|
| - EXPECT_EQ(ERR_QUIC_PROTOCOL_ERROR, delegate->error());
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterSendData) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckAndDataPacket(2, !kIncludeVersion, 2, 1, !kFin, 0,
|
| - kUploadData));
|
| - AddWrite(ConstructRstStreamCancelledPacket(3, strlen(kUploadData)));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - // Send a DATA frame.
|
| - scoped_refptr<StringIOBuffer> buf(new StringIOBuffer(kUploadData));
|
| -
|
| - delegate->SendData(buf.get(), buf->size(), false);
|
| - delegate->WaitUntilNextCallback(); // OnDataSent
|
| -
|
| - delegate->CancelStream();
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(1, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length +
|
| - strlen(kUploadData)),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, SessionClosedBeforeReadData) {
|
| - SetRequest("GET", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "GET";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = true;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - size_t spdy_response_headers_frame_length;
|
| - QuicStreamOffset offset = 0;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - session()->connection()->CloseConnection(QUIC_NO_ERROR,
|
| - ConnectionCloseSource::FROM_PEER);
|
| - delegate->WaitUntilNextCallback(); // OnFailed
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(ERR_UNEXPECTED, delegate->ReadData(cb.callback()));
|
| - EXPECT_EQ(ERR_UNEXPECTED, delegate->error());
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, CancelStreamAfterReadData) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<TestDelegateBase> delegate(
|
| - new TestDelegateBase(read_buffer.get(), kReadBufferSize));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length, 0));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - // Cancel the stream after ReadData returns ERR_IO_PENDING.
|
| - TestCompletionCallback cb;
|
| - EXPECT_EQ(ERR_IO_PENDING, delegate->ReadData(cb.callback()));
|
| - delegate->CancelStream();
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| - EXPECT_EQ(kProtoQUIC1SPDY3, delegate->GetProtocol());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_request_headers_frame_length),
|
| - delegate->GetTotalSentBytes());
|
| - EXPECT_EQ(static_cast<int64_t>(spdy_response_headers_frame_length),
|
| - delegate->GetTotalReceivedBytes());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnHeadersReceived) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckAndRstStreamPacket(2, 2, 1, 1));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
|
| - read_buffer.get(), kReadBufferSize,
|
| - DeleteStreamDelegate::ON_HEADERS_RECEIVED, true));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - nullptr));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(0, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnDataRead) {
|
| - SetRequest("POST", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, !kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckPacket(2, 3, 1));
|
| - AddWrite(ConstructRstStreamPacket(3));
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "POST";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = false;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<DeleteStreamDelegate> delegate(
|
| - new DeleteStreamDelegate(read_buffer.get(), kReadBufferSize,
|
| - DeleteStreamDelegate::ON_DATA_READ, true));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - nullptr));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| -
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - const char kResponseBody[] = "Hello world!";
|
| - // Server sends data.
|
| - ProcessPacket(
|
| - ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
|
| - EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(1, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| -}
|
| -
|
| -TEST_P(BidirectionalStreamQuicImplTest, DeleteStreamDuringOnTrailersReceived) {
|
| - SetRequest("GET", "/", DEFAULT_PRIORITY);
|
| - size_t spdy_request_headers_frame_length;
|
| - AddWrite(ConstructRequestHeadersPacket(1, kFin, DEFAULT_PRIORITY,
|
| - &spdy_request_headers_frame_length));
|
| - AddWrite(ConstructAckPacket(2, 3, 1)); // Ack the data packet
|
| -
|
| - Initialize();
|
| -
|
| - BidirectionalStreamRequestInfo request;
|
| - request.method = "GET";
|
| - request.url = GURL("http://www.google.com/");
|
| - request.end_stream_on_headers = true;
|
| - request.priority = DEFAULT_PRIORITY;
|
| -
|
| - scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize));
|
| - scoped_ptr<DeleteStreamDelegate> delegate(new DeleteStreamDelegate(
|
| - read_buffer.get(), kReadBufferSize,
|
| - DeleteStreamDelegate::ON_TRAILERS_RECEIVED, true));
|
| - delegate->Start(&request, net_log(), session()->GetWeakPtr());
|
| - delegate->WaitUntilNextCallback(); // OnHeadersSent
|
| -
|
| - // Server acks the request.
|
| - ProcessPacket(ConstructAckPacket(1, 0, 0));
|
| -
|
| - // Server sends the response headers.
|
| - SpdyHeaderBlock response_headers = ConstructResponseHeaders("200");
|
| -
|
| - QuicStreamOffset offset = 0;
|
| - size_t spdy_response_headers_frame_length;
|
| - ProcessPacket(ConstructResponseHeadersPacket(
|
| - 2, !kFin, response_headers, &spdy_response_headers_frame_length,
|
| - &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnHeadersReceived
|
| -
|
| - EXPECT_EQ("200", delegate->response_headers().find(":status")->second);
|
| -
|
| - TestCompletionCallback cb;
|
| - int rv = delegate->ReadData(cb.callback());
|
| - EXPECT_EQ(ERR_IO_PENDING, rv);
|
| - const char kResponseBody[] = "Hello world!";
|
| - // Server sends data.
|
| - ProcessPacket(
|
| - ConstructDataPacket(3, !kIncludeVersion, !kFin, 0, kResponseBody));
|
| -
|
| - EXPECT_EQ(static_cast<int64_t>(strlen(kResponseBody)), cb.WaitForResult());
|
| - EXPECT_EQ(std::string(kResponseBody), delegate->data_received());
|
| -
|
| - size_t spdy_trailers_frame_length;
|
| - SpdyHeaderBlock trailers;
|
| - trailers["foo"] = "bar";
|
| - trailers[kFinalOffsetHeaderKey] = base::IntToString(strlen(kResponseBody));
|
| - // Server sends trailers.
|
| - ProcessPacket(ConstructResponseTrailersPacket(
|
| - 4, kFin, trailers, &spdy_trailers_frame_length, &offset));
|
| -
|
| - delegate->WaitUntilNextCallback(); // OnTrailersReceived
|
| - trailers.erase(kFinalOffsetHeaderKey);
|
| - EXPECT_EQ(trailers, delegate->trailers());
|
| -
|
| - base::MessageLoop::current()->RunUntilIdle();
|
| -
|
| - EXPECT_EQ(1, delegate->on_data_read_count());
|
| - EXPECT_EQ(0, delegate->on_data_sent_count());
|
| -}
|
| -
|
| -} // namespace test
|
| -
|
| -} // namespace net
|
|
|