diff options
Diffstat (limited to 'chromium/net/spdy')
79 files changed, 4922 insertions, 3271 deletions
diff --git a/chromium/net/spdy/bidirectional_stream_spdy_impl.cc b/chromium/net/spdy/bidirectional_stream_spdy_impl.cc index c7e023baeb4..6a394c2ff61 100644 --- a/chromium/net/spdy/bidirectional_stream_spdy_impl.cc +++ b/chromium/net/spdy/bidirectional_stream_spdy_impl.cc @@ -41,17 +41,15 @@ BidirectionalStreamSpdyImpl::BidirectionalStreamSpdyImpl( weak_factory_(this) {} BidirectionalStreamSpdyImpl::~BidirectionalStreamSpdyImpl() { - if (stream_) { - stream_->DetachDelegate(); - DCHECK(!stream_); - } + Cancel(); } void BidirectionalStreamSpdyImpl::Start( const BidirectionalStreamRequestInfo* request_info, const BoundNetLog& net_log, + bool /*send_request_headers_automatically*/, BidirectionalStreamImpl::Delegate* delegate, - scoped_ptr<base::Timer> timer) { + std::unique_ptr<base::Timer> timer) { DCHECK(!stream_); DCHECK(timer); @@ -59,7 +57,10 @@ void BidirectionalStreamSpdyImpl::Start( timer_ = std::move(timer); if (!spdy_session_) { - delegate_->OnFailed(ERR_CONNECTION_CLOSED); + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, + base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, + weak_factory_.GetWeakPtr(), ERR_CONNECTION_CLOSED)); return; } @@ -74,6 +75,11 @@ void BidirectionalStreamSpdyImpl::Start( OnStreamInitialized(rv); } +void BidirectionalStreamSpdyImpl::SendRequestHeaders() { + // Request headers will be sent automatically. + NOTREACHED(); +} + int BidirectionalStreamSpdyImpl::ReadData(IOBuffer* buf, int buf_len) { if (stream_) DCHECK(!stream_->IsIdle()); @@ -95,22 +101,63 @@ int BidirectionalStreamSpdyImpl::ReadData(IOBuffer* buf, int buf_len) { return ERR_IO_PENDING; } -void BidirectionalStreamSpdyImpl::SendData(IOBuffer* data, +void BidirectionalStreamSpdyImpl::SendData(const scoped_refptr<IOBuffer>& data, int length, bool end_stream) { + DCHECK(length > 0 || (length == 0 && end_stream)); + + if (!stream_) { + LOG(ERROR) << "Trying to send data after stream has been destroyed."; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, + weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); + return; + } + DCHECK(!stream_closed_); - DCHECK(stream_); + stream_->SendData(data.get(), length, + end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); +} - stream_->SendData(data, length, +void BidirectionalStreamSpdyImpl::SendvData( + const std::vector<scoped_refptr<IOBuffer>>& buffers, + const std::vector<int>& lengths, + bool end_stream) { + DCHECK_EQ(buffers.size(), lengths.size()); + + if (!stream_) { + LOG(ERROR) << "Trying to send data after stream has been destroyed."; + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::Bind(&BidirectionalStreamSpdyImpl::NotifyError, + weak_factory_.GetWeakPtr(), ERR_UNEXPECTED)); + return; + } + + DCHECK(!stream_closed_); + int total_len = 0; + for (int len : lengths) { + total_len += len; + } + + pending_combined_buffer_ = new net::IOBuffer(total_len); + int len = 0; + // TODO(xunjieli): Get rid of extra copy. Coalesce headers and data frames. + for (size_t i = 0; i < buffers.size(); ++i) { + memcpy(pending_combined_buffer_->data() + len, buffers[i]->data(), + lengths[i]); + len += lengths[i]; + } + stream_->SendData(pending_combined_buffer_.get(), total_len, end_stream ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND); } void BidirectionalStreamSpdyImpl::Cancel() { - if (!stream_) - return; - // Cancels the stream and detaches the delegate so it doesn't get called back. - stream_->DetachDelegate(); - DCHECK(!stream_); + if (delegate_) { + delegate_ = nullptr; + // Cancel any pending callback. + weak_factory_.InvalidateWeakPtrs(); + } + ResetStream(); } NextProto BidirectionalStreamSpdyImpl::GetProtocol() const { @@ -141,19 +188,22 @@ void BidirectionalStreamSpdyImpl::OnRequestHeadersSent() { DCHECK(stream_); negotiated_protocol_ = stream_->GetProtocol(); - delegate_->OnHeadersSent(); + if (delegate_) + delegate_->OnStreamReady(/*request_headers_sent=*/true); } SpdyResponseHeadersStatus BidirectionalStreamSpdyImpl::OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) { DCHECK(stream_); - delegate_->OnHeadersReceived(response_headers); + if (delegate_) + delegate_->OnHeadersReceived(response_headers); + return RESPONSE_HEADERS_ARE_COMPLETE; } void BidirectionalStreamSpdyImpl::OnDataReceived( - scoped_ptr<SpdyBuffer> buffer) { + std::unique_ptr<SpdyBuffer> buffer) { DCHECK(stream_); DCHECK(!stream_closed_); @@ -176,14 +226,17 @@ void BidirectionalStreamSpdyImpl::OnDataSent() { DCHECK(stream_); DCHECK(!stream_closed_); - delegate_->OnDataSent(); + pending_combined_buffer_ = nullptr; + if (delegate_) + delegate_->OnDataSent(); } void BidirectionalStreamSpdyImpl::OnTrailers(const SpdyHeaderBlock& trailers) { DCHECK(stream_); DCHECK(!stream_closed_); - delegate_->OnTrailersReceived(trailers); + if (delegate_) + delegate_->OnTrailersReceived(trailers); } void BidirectionalStreamSpdyImpl::OnClose(int status) { @@ -193,12 +246,12 @@ void BidirectionalStreamSpdyImpl::OnClose(int status) { closed_stream_status_ = status; closed_stream_received_bytes_ = stream_->raw_received_bytes(); closed_stream_sent_bytes_ = stream_->raw_sent_bytes(); - stream_.reset(); if (status != OK) { - delegate_->OnFailed(status); + NotifyError(status); return; } + ResetStream(); // Complete any remaining read, as all data has been buffered. // If user has not called ReadData (i.e |read_buffer_| is nullptr), this will // do nothing. @@ -206,8 +259,8 @@ void BidirectionalStreamSpdyImpl::OnClose(int status) { DoBufferedRead(); } -void BidirectionalStreamSpdyImpl::SendRequestHeaders() { - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); +int BidirectionalStreamSpdyImpl::SendRequestHeadersHelper() { + std::unique_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); HttpRequestInfo http_request_info; http_request_info.url = request_info_->url; http_request_info.method = request_info_->method; @@ -216,10 +269,10 @@ void BidirectionalStreamSpdyImpl::SendRequestHeaders() { CreateSpdyHeadersFromHttpRequest( http_request_info, http_request_info.extra_headers, stream_->GetProtocolVersion(), true, headers.get()); - stream_->SendRequestHeaders(std::move(headers), - request_info_->end_stream_on_headers - ? NO_MORE_DATA_TO_SEND - : MORE_DATA_TO_SEND); + return stream_->SendRequestHeaders(std::move(headers), + request_info_->end_stream_on_headers + ? NO_MORE_DATA_TO_SEND + : MORE_DATA_TO_SEND); } void BidirectionalStreamSpdyImpl::OnStreamInitialized(int rv) { @@ -227,10 +280,40 @@ void BidirectionalStreamSpdyImpl::OnStreamInitialized(int rv) { if (rv == OK) { stream_ = stream_request_.ReleaseStream(); stream_->SetDelegate(this); - SendRequestHeaders(); + rv = SendRequestHeadersHelper(); + if (rv == OK) { + OnRequestHeadersSent(); + return; + } else if (rv == ERR_IO_PENDING) { + return; + } + } + NotifyError(rv); +} + +void BidirectionalStreamSpdyImpl::NotifyError(int rv) { + ResetStream(); + if (delegate_) { + BidirectionalStreamImpl::Delegate* delegate = delegate_; + delegate_ = nullptr; + // Cancel any pending callback. + weak_factory_.InvalidateWeakPtrs(); + delegate->OnFailed(rv); + // |this| can be null when returned from delegate. + } +} + +void BidirectionalStreamSpdyImpl::ResetStream() { + if (!stream_) return; + if (!stream_->IsClosed()) { + // This sends a RST to the remote. + stream_->DetachDelegate(); + DCHECK(!stream_); + } else { + // Stream is already closed, so it is not legal to call DetachDelegate. + stream_.reset(); } - delegate_->OnFailed(rv); } void BidirectionalStreamSpdyImpl::ScheduleBufferedRead() { @@ -266,7 +349,8 @@ void BidirectionalStreamSpdyImpl::DoBufferedRead() { DCHECK_NE(ERR_IO_PENDING, rv); read_buffer_ = nullptr; read_buffer_len_ = 0; - delegate_->OnDataRead(rv); + if (delegate_) + delegate_->OnDataRead(rv); } } diff --git a/chromium/net/spdy/bidirectional_stream_spdy_impl.h b/chromium/net/spdy/bidirectional_stream_spdy_impl.h index 62e7bb66f00..b40c1ff9aaf 100644 --- a/chromium/net/spdy/bidirectional_stream_spdy_impl.h +++ b/chromium/net/spdy/bidirectional_stream_spdy_impl.h @@ -7,8 +7,11 @@ #include <stdint.h> +#include <memory> +#include <vector> + #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "net/http/bidirectional_stream_impl.h" #include "net/http/bidirectional_stream_request_info.h" @@ -39,10 +42,17 @@ class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl // BidirectionalStreamImpl implementation: void Start(const BidirectionalStreamRequestInfo* request_info, const BoundNetLog& net_log, + bool send_request_headers_automatically, BidirectionalStreamImpl::Delegate* delegate, - scoped_ptr<base::Timer> timer) override; + std::unique_ptr<base::Timer> timer) override; + void SendRequestHeaders() override; int ReadData(IOBuffer* buf, int buf_len) override; - void SendData(IOBuffer* data, int length, bool end_stream) override; + void SendData(const scoped_refptr<IOBuffer>& data, + int length, + bool end_stream) override; + void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers, + const std::vector<int>& lengths, + bool end_stream) override; void Cancel() override; NextProto GetProtocol() const override; int64_t GetTotalReceivedBytes() const override; @@ -52,14 +62,17 @@ class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl void OnRequestHeadersSent() override; SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) override; - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; void OnDataSent() override; void OnTrailers(const SpdyHeaderBlock& trailers) override; void OnClose(int status) override; private: - void SendRequestHeaders(); + int SendRequestHeadersHelper(); void OnStreamInitialized(int rv); + // Notifies delegate of an error. + void NotifyError(int rv); + void ResetStream(); void ScheduleBufferedRead(); void DoBufferedRead(); bool ShouldWaitForMoreBufferedData() const; @@ -67,7 +80,7 @@ class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl const base::WeakPtr<SpdySession> spdy_session_; const BidirectionalStreamRequestInfo* request_info_; BidirectionalStreamImpl::Delegate* delegate_; - scoped_ptr<base::Timer> timer_; + std::unique_ptr<base::Timer> timer_; SpdyStreamRequest stream_request_; base::WeakPtr<SpdyStream> stream_; @@ -91,6 +104,9 @@ class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl // After |stream_| has been closed, this keeps track of the total number of // bytes sent over the network for |stream_| while it was open. int64_t closed_stream_sent_bytes_; + // This is the combined buffer of buffers passed in through SendvData. + // Keep a reference here so it is alive until OnDataSent is invoked. + scoped_refptr<IOBuffer> pending_combined_buffer_; base::WeakPtrFactory<BidirectionalStreamSpdyImpl> weak_factory_; diff --git a/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc b/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc new file mode 100644 index 00000000000..7e56cfee04c --- /dev/null +++ b/chromium/net/spdy/bidirectional_stream_spdy_impl_unittest.cc @@ -0,0 +1,373 @@ +// 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/spdy/bidirectional_stream_spdy_impl.h" + +#include <memory> +#include <string> + +#include "base/macros.h" +#include "base/memory/ptr_util.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_piece.h" +#include "base/time/time.h" +#include "base/timer/mock_timer.h" +#include "net/base/net_errors.h" +#include "net/base/test_data_directory.h" +#include "net/http/http_request_info.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_response_info.h" +#include "net/log/net_log.h" +#include "net/log/test_net_log.h" +#include "net/socket/socket_test_util.h" +#include "net/spdy/spdy_session.h" +#include "net/spdy/spdy_test_util_common.h" +#include "net/test/cert_test_util.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace { + +const char kBodyData[] = "Body data"; +const size_t kBodyDataSize = arraysize(kBodyData); +// Size of the buffer to be allocated for each read. +const size_t kReadBufferSize = 4096; + +class TestDelegateBase : public BidirectionalStreamImpl::Delegate { + public: + TestDelegateBase(base::WeakPtr<SpdySession> session, + IOBuffer* read_buf, + int read_buf_len) + : stream_(new BidirectionalStreamSpdyImpl(session)), + read_buf_(read_buf), + read_buf_len_(read_buf_len), + loop_(nullptr), + error_(OK), + bytes_read_(0), + on_data_read_count_(0), + on_data_sent_count_(0), + do_not_start_read_(false), + run_until_completion_(false), + not_expect_callback_(false), + on_failed_called_(false) {} + + ~TestDelegateBase() override {} + + void OnStreamReady(bool request_headers_sent) override { + CHECK(!on_failed_called_); + } + + void OnHeadersReceived(const SpdyHeaderBlock& response_headers) override { + CHECK(!on_failed_called_); + CHECK(!not_expect_callback_); + response_headers_ = response_headers; + if (!do_not_start_read_) + StartOrContinueReading(); + } + + void OnDataRead(int bytes_read) override { + CHECK(!on_failed_called_); + CHECK(!not_expect_callback_); + on_data_read_count_++; + CHECK_GE(bytes_read, OK); + bytes_read_ += bytes_read; + data_received_.append(read_buf_->data(), bytes_read); + if (!do_not_start_read_) + StartOrContinueReading(); + } + + void OnDataSent() override { + CHECK(!on_failed_called_); + CHECK(!not_expect_callback_); + on_data_sent_count_++; + } + + void OnTrailersReceived(const SpdyHeaderBlock& trailers) override { + CHECK(!on_failed_called_); + trailers_ = trailers; + if (run_until_completion_) + loop_->Quit(); + } + + void OnFailed(int error) override { + CHECK(!on_failed_called_); + CHECK(!not_expect_callback_); + CHECK_NE(OK, error); + error_ = error; + on_failed_called_ = true; + if (run_until_completion_) + loop_->Quit(); + } + + void Start(const BidirectionalStreamRequestInfo* request, + const BoundNetLog& net_log) { + stream_->Start(request, net_log, + /*send_request_headers_automatically=*/false, this, + base::WrapUnique(new base::Timer(false, false))); + not_expect_callback_ = false; + } + + void SendData(IOBuffer* data, int length, bool end_of_stream) { + not_expect_callback_ = true; + stream_->SendData(data, length, end_of_stream); + not_expect_callback_ = false; + } + + void SendvData(const std::vector<scoped_refptr<IOBuffer>>& data, + const std::vector<int>& length, + bool end_of_stream) { + not_expect_callback_ = true; + stream_->SendvData(data, length, end_of_stream); + not_expect_callback_ = false; + } + + // Sets whether the delegate should wait until the completion of the stream. + void SetRunUntilCompletion(bool run_until_completion) { + run_until_completion_ = run_until_completion; + loop_.reset(new base::RunLoop); + } + + // Starts or continues read data from |stream_| until there is no more + // byte can be read synchronously. + void StartOrContinueReading() { + int rv = ReadData(); + while (rv > 0) { + rv = ReadData(); + } + if (run_until_completion_ && rv == 0) + loop_->Quit(); + } + + // Calls ReadData on the |stream_| and updates internal states. + int ReadData() { + int rv = stream_->ReadData(read_buf_.get(), read_buf_len_); + if (rv > 0) { + data_received_.append(read_buf_->data(), rv); + bytes_read_ += rv; + } + return rv; + } + + NextProto GetProtocol() const { return stream_->GetProtocol(); } + + int64_t GetTotalReceivedBytes() const { + return stream_->GetTotalReceivedBytes(); + } + + int64_t GetTotalSentBytes() const { return stream_->GetTotalSentBytes(); } + + // Const getters for internal states. + const std::string& data_received() const { return data_received_; } + int bytes_read() const { return bytes_read_; } + 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_; } + bool on_failed_called() const { return on_failed_called_; } + + // Sets whether the delegate should automatically start reading. + void set_do_not_start_read(bool do_not_start_read) { + do_not_start_read_ = do_not_start_read; + } + + // Cancels |stream_|. + void CancelStream() { stream_->Cancel(); } + + private: + std::unique_ptr<BidirectionalStreamSpdyImpl> stream_; + scoped_refptr<IOBuffer> read_buf_; + int read_buf_len_; + std::string data_received_; + std::unique_ptr<base::RunLoop> loop_; + SpdyHeaderBlock response_headers_; + SpdyHeaderBlock trailers_; + int error_; + int bytes_read_; + int on_data_read_count_; + int on_data_sent_count_; + bool do_not_start_read_; + bool run_until_completion_; + bool not_expect_callback_; + bool on_failed_called_; + + DISALLOW_COPY_AND_ASSIGN(TestDelegateBase); +}; + +} // namespace + +class BidirectionalStreamSpdyImplTest : public testing::Test { + public: + BidirectionalStreamSpdyImplTest() + : spdy_util_(kProtoHTTP2, true), + session_deps_(kProtoHTTP2), + ssl_data_(SSLSocketDataProvider(ASYNC, OK)) { + ssl_data_.SetNextProto(kProtoHTTP2); + ssl_data_.cert = ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem"); + } + + protected: + void TearDown() override { + if (sequenced_data_) { + EXPECT_TRUE(sequenced_data_->AllReadDataConsumed()); + EXPECT_TRUE(sequenced_data_->AllWriteDataConsumed()); + } + } + + // Initializes the session using SequencedSocketData. + void InitSession(MockRead* reads, + size_t reads_count, + MockWrite* writes, + size_t writes_count, + const SpdySessionKey& key) { + ASSERT_TRUE(ssl_data_.cert.get()); + session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl_data_); + sequenced_data_.reset( + new SequencedSocketData(reads, reads_count, writes, writes_count)); + session_deps_.socket_factory->AddSocketDataProvider(sequenced_data_.get()); + session_deps_.net_log = net_log_.bound().net_log(); + http_session_ = SpdySessionDependencies::SpdyCreateSession(&session_deps_); + session_ = + CreateSecureSpdySession(http_session_.get(), key, net_log_.bound()); + } + + BoundTestNetLog net_log_; + SpdyTestUtil spdy_util_; + SpdySessionDependencies session_deps_; + std::unique_ptr<SequencedSocketData> sequenced_data_; + std::unique_ptr<HttpNetworkSession> http_session_; + base::WeakPtr<SpdySession> session_; + + private: + SSLSocketDataProvider ssl_data_; +}; + +TEST_F(BidirectionalStreamSpdyImplTest, SendDataAfterStreamFailed) { + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + "https://www.example.org", 1, kBodyDataSize * 3, LOW, nullptr, 0)); + std::unique_ptr<SpdySerializedFrame> rst( + spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); + + MockWrite writes[] = { + CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2), + }; + + const char* const kExtraHeaders[] = {"X-UpperCase", "yes"}; + std::unique_ptr<SpdySerializedFrame> resp( + spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1)); + + MockRead reads[] = { + CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3), + }; + + HostPortPair host_port_pair("www.example.org", 443); + SpdySessionKey key(host_port_pair, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED); + InitSession(reads, arraysize(reads), writes, arraysize(writes), key); + + BidirectionalStreamRequestInfo request_info; + request_info.method = "POST"; + request_info.url = GURL("https://www.example.org/"); + request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, + base::SizeTToString(kBodyDataSize * 3)); + + scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); + std::unique_ptr<TestDelegateBase> delegate( + new TestDelegateBase(session_, read_buffer.get(), kReadBufferSize)); + delegate->SetRunUntilCompletion(true); + delegate->Start(&request_info, net_log_.bound()); + base::RunLoop().RunUntilIdle(); + + EXPECT_TRUE(delegate->on_failed_called()); + + // Try to send data after OnFailed(), should not get called back. + scoped_refptr<StringIOBuffer> buf(new StringIOBuffer("dummy")); + delegate->SendData(buf.get(), buf->size(), false); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(ERR_SPDY_PROTOCOL_ERROR, delegate->error()); + EXPECT_EQ(0, delegate->on_data_read_count()); + EXPECT_EQ(0, delegate->on_data_sent_count()); + EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); + // BidirectionalStreamSpdyStreamJob does not count the bytes sent for |rst| + // because it is sent after SpdyStream::Delegate::OnClose is called. + EXPECT_EQ(CountWriteBytes(writes, 1), delegate->GetTotalSentBytes()); + EXPECT_EQ(CountReadBytes(reads, arraysize(reads)), + delegate->GetTotalReceivedBytes()); +} + +TEST_F(BidirectionalStreamSpdyImplTest, SendDataAfterCancelStream) { + BufferedSpdyFramer framer(spdy_util_.spdy_version()); + + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + "https://www.example.org", 1, kBodyDataSize * 3, LOWEST, nullptr, 0)); + std::unique_ptr<SpdySerializedFrame> data_frame( + framer.CreateDataFrame(1, kBodyData, kBodyDataSize, DATA_FLAG_NONE)); + std::unique_ptr<SpdySerializedFrame> rst( + spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); + + MockWrite writes[] = { + CreateMockWrite(*req, 0), CreateMockWrite(*data_frame, 3), + CreateMockWrite(*rst, 5), + }; + + std::unique_ptr<SpdySerializedFrame> resp( + spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); + std::unique_ptr<SpdySerializedFrame> response_body_frame( + spdy_util_.ConstructSpdyBodyFrame(1, false)); + + MockRead reads[] = { + CreateMockRead(*resp, 1), + MockRead(ASYNC, ERR_IO_PENDING, 2), // Force a pause. + MockRead(ASYNC, ERR_IO_PENDING, 4), // Force a pause. + MockRead(ASYNC, 0, 6), + }; + + HostPortPair host_port_pair("www.example.org", 443); + SpdySessionKey key(host_port_pair, ProxyServer::Direct(), + PRIVACY_MODE_DISABLED); + InitSession(reads, arraysize(reads), writes, arraysize(writes), key); + + BidirectionalStreamRequestInfo request_info; + request_info.method = "POST"; + request_info.url = GURL("https://www.example.org/"); + request_info.priority = LOWEST; + request_info.extra_headers.SetHeader(net::HttpRequestHeaders::kContentLength, + base::SizeTToString(kBodyDataSize * 3)); + + scoped_refptr<IOBuffer> read_buffer(new IOBuffer(kReadBufferSize)); + std::unique_ptr<TestDelegateBase> delegate( + new TestDelegateBase(session_, read_buffer.get(), kReadBufferSize)); + delegate->set_do_not_start_read(true); + delegate->Start(&request_info, net_log_.bound()); + // Send the request and receive response headers. + sequenced_data_->RunUntilPaused(); + EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); + + // Send a DATA frame. + scoped_refptr<StringIOBuffer> buf( + new StringIOBuffer(std::string(kBodyData, kBodyDataSize))); + delegate->SendData(buf.get(), buf->size(), false); + sequenced_data_->Resume(); + base::RunLoop().RunUntilIdle(); + // Cancel the stream. + delegate->CancelStream(); + sequenced_data_->Resume(); + base::RunLoop().RunUntilIdle(); + + // Try to send data after Cancel(), should not get called back. + delegate->SendData(buf.get(), buf->size(), false); + base::MessageLoop::current()->RunUntilIdle(); + EXPECT_FALSE(delegate->on_failed_called()); + + EXPECT_EQ("200", delegate->response_headers().find(":status")->second); + EXPECT_EQ(0, delegate->on_data_read_count()); + EXPECT_EQ(kProtoHTTP2, delegate->GetProtocol()); + EXPECT_EQ(0, delegate->GetTotalSentBytes()); + EXPECT_EQ(0, delegate->GetTotalReceivedBytes()); +} + +} // namespace net diff --git a/chromium/net/spdy/buffered_spdy_framer.cc b/chromium/net/spdy/buffered_spdy_framer.cc index ba0f4583fe3..4dd34ceda53 100644 --- a/chromium/net/spdy/buffered_spdy_framer.cc +++ b/chromium/net/spdy/buffered_spdy_framer.cc @@ -196,13 +196,12 @@ void BufferedSpdyFramer::OnDataFrameHeader(SpdyStreamId stream_id, void BufferedSpdyFramer::OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) { - visitor_->OnStreamFrameData(stream_id, data, len, fin); + size_t len) { + visitor_->OnStreamFrameData(stream_id, data, len); } void BufferedSpdyFramer::OnStreamEnd(SpdyStreamId stream_id) { - visitor_->OnStreamFrameData(stream_id, nullptr, 0, true); + visitor_->OnStreamEnd(stream_id); } void BufferedSpdyFramer::OnStreamPadding(SpdyStreamId stream_id, size_t len) { diff --git a/chromium/net/spdy/buffered_spdy_framer.h b/chromium/net/spdy/buffered_spdy_framer.h index 8ad0defed0f..87283b0f6f1 100644 --- a/chromium/net/spdy/buffered_spdy_framer.h +++ b/chromium/net/spdy/buffered_spdy_framer.h @@ -8,10 +8,10 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" #include "net/socket/next_proto.h" #include "net/spdy/spdy_framer.h" @@ -68,12 +68,13 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramerVisitorInterface { // |data| A buffer containing the data received. // |len| The length of the data buffer (at most 2^24 - 1 for SPDY/3, // but 2^16 - 1 - 8 for SPDY/4). - // When the other side has finished sending data on this stream, - // this method will be called with a zero-length buffer. virtual void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) = 0; + size_t len) = 0; + + // Called when the other side has finished sending data on this stream. + // |stream_id| The stream that was receivin data. + virtual void OnStreamEnd(SpdyStreamId stream_id) = 0; // Called when padding is received (padding length field or padding octets). // |stream_id| The stream receiving data. @@ -179,8 +180,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer size_t len) override; void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override; + size_t len) override; void OnStreamEnd(SpdyStreamId stream_id) override; void OnStreamPadding(SpdyStreamId stream_id, size_t len) override; SpdyHeadersHandlerInterface* OnHeaderFrameStart( @@ -301,7 +301,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer bool fin; bool unidirectional; }; - scoped_ptr<ControlFrameFields> control_frame_fields_; + std::unique_ptr<ControlFrameFields> control_frame_fields_; // Collection of fields of a GOAWAY frame that this class needs to buffer. struct GoAwayFields { @@ -309,7 +309,7 @@ class NET_EXPORT_PRIVATE BufferedSpdyFramer SpdyGoAwayStatus status; std::string debug_data; }; - scoped_ptr<GoAwayFields> goaway_fields_; + std::unique_ptr<GoAwayFields> goaway_fields_; DISALLOW_COPY_AND_ASSIGN(BufferedSpdyFramer); }; diff --git a/chromium/net/spdy/buffered_spdy_framer_unittest.cc b/chromium/net/spdy/buffered_spdy_framer_unittest.cc index be2d66e6036..90f45603788 100644 --- a/chromium/net/spdy/buffered_spdy_framer_unittest.cc +++ b/chromium/net/spdy/buffered_spdy_framer_unittest.cc @@ -4,6 +4,7 @@ #include "net/spdy/buffered_spdy_framer.h" +#include "base/logging.h" #include "net/spdy/spdy_test_util_common.h" #include "testing/platform_test.h" @@ -26,14 +27,14 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { promised_stream_id_(static_cast<SpdyStreamId>(-1)) {} void OnError(SpdyFramer::SpdyError error_code) override { - LOG(INFO) << "SpdyFramer Error: " << error_code; + VLOG(1) << "SpdyFramer Error: " << error_code; error_count_++; } void OnStreamError(SpdyStreamId stream_id, const std::string& description) override { - LOG(INFO) << "SpdyFramer Error on stream: " << stream_id << " " - << description; + VLOG(1) << "SpdyFramer Error on stream: " << stream_id << " " + << description; error_count_++; } @@ -79,11 +80,14 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override { + size_t len) override { LOG(FATAL) << "Unexpected OnStreamFrameData call."; } + void OnStreamEnd(SpdyStreamId stream_id) override { + LOG(FATAL) << "Unexpected OnStreamEnd call."; + } + void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { LOG(FATAL) << "Unexpected OnStreamPadding call."; } @@ -111,7 +115,7 @@ class TestBufferedSpdyVisitor : public BufferedSpdyFramerVisitorInterface { void OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status, - StringPiece debug_data) override { + base::StringPiece debug_data) override { goaway_count_++; goaway_last_accepted_stream_id_ = last_accepted_stream_id; goaway_status_ = status; @@ -227,7 +231,7 @@ TEST_P(BufferedSpdyFramerTest, ReadSynStreamHeaderBlock) { headers["aa"] = "vv"; headers["bb"] = "ww"; BufferedSpdyFramer framer(spdy_version()); - scoped_ptr<SpdySerializedFrame> control_frame( + std::unique_ptr<SpdySerializedFrame> control_frame( framer.CreateSynStream(1, // stream_id 0, // associated_stream_id 1, // priority @@ -255,7 +259,7 @@ TEST_P(BufferedSpdyFramerTest, ReadSynReplyHeaderBlock) { headers["alpha"] = "beta"; headers["gamma"] = "delta"; BufferedSpdyFramer framer(spdy_version()); - scoped_ptr<SpdySerializedFrame> control_frame( + std::unique_ptr<SpdySerializedFrame> control_frame( framer.CreateSynReply(1, // stream_id CONTROL_FLAG_NONE, &headers)); EXPECT_TRUE(control_frame.get() != NULL); @@ -282,7 +286,7 @@ TEST_P(BufferedSpdyFramerTest, ReadHeadersHeaderBlock) { headers["alpha"] = "beta"; headers["gamma"] = "delta"; BufferedSpdyFramer framer(spdy_version()); - scoped_ptr<SpdySerializedFrame> control_frame( + std::unique_ptr<SpdySerializedFrame> control_frame( framer.CreateHeaders(1, // stream_id CONTROL_FLAG_NONE, 0, // priority @@ -308,7 +312,7 @@ TEST_P(BufferedSpdyFramerTest, ReadPushPromiseHeaderBlock) { headers["alpha"] = "beta"; headers["gamma"] = "delta"; BufferedSpdyFramer framer(spdy_version()); - scoped_ptr<SpdySerializedFrame> control_frame( + std::unique_ptr<SpdySerializedFrame> control_frame( framer.CreatePushPromise(1, 2, &headers)); EXPECT_TRUE(control_frame.get() != NULL); @@ -330,7 +334,7 @@ TEST_P(BufferedSpdyFramerTest, GoAwayDebugData) { if (spdy_version() < HTTP2) return; BufferedSpdyFramer framer(spdy_version()); - scoped_ptr<SpdySerializedFrame> goaway_frame( + std::unique_ptr<SpdySerializedFrame> goaway_frame( framer.CreateGoAway(2u, GOAWAY_FRAME_SIZE_ERROR, "foo")); TestBufferedSpdyVisitor visitor(spdy_version()); diff --git a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h b/chromium/net/spdy/fuzzing/hpack_fuzz_util.h index 3ee64e6b3fe..289bb6a1646 100644 --- a/chromium/net/spdy/fuzzing/hpack_fuzz_util.h +++ b/chromium/net/spdy/fuzzing/hpack_fuzz_util.h @@ -8,10 +8,10 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include <vector> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "net/base/net_export.h" #include "net/spdy/hpack/hpack_decoder.h" @@ -69,9 +69,9 @@ class NET_EXPORT_PRIVATE HpackFuzzUtil { struct NET_EXPORT_PRIVATE FuzzerContext { FuzzerContext(); ~FuzzerContext(); - scoped_ptr<HpackDecoder> first_stage; - scoped_ptr<HpackEncoder> second_stage; - scoped_ptr<HpackDecoder> third_stage; + std::unique_ptr<HpackDecoder> first_stage; + std::unique_ptr<HpackEncoder> second_stage; + std::unique_ptr<HpackDecoder> third_stage; }; static void InitializeFuzzerContext(FuzzerContext* context); diff --git a/chromium/net/spdy/hpack/hpack_constants.cc b/chromium/net/spdy/hpack/hpack_constants.cc index 59a55dac96a..b9db0ef2d6c 100644 --- a/chromium/net/spdy/hpack/hpack_constants.cc +++ b/chromium/net/spdy/hpack/hpack_constants.cc @@ -4,10 +4,10 @@ #include "net/spdy/hpack/hpack_constants.h" +#include <memory> #include <vector> #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/singleton.h" #include "net/spdy/hpack/hpack_huffman_table.h" #include "net/spdy/hpack/hpack_static_table.h" @@ -22,7 +22,7 @@ struct SharedHpackHuffmanTable { public: SharedHpackHuffmanTable() { std::vector<HpackHuffmanSymbol> code = HpackHuffmanCode(); - scoped_ptr<HpackHuffmanTable> mutable_table(new HpackHuffmanTable()); + std::unique_ptr<HpackHuffmanTable> mutable_table(new HpackHuffmanTable()); CHECK(mutable_table->Initialize(&code[0], code.size())); CHECK(mutable_table->IsInitialized()); table.reset(mutable_table.release()); @@ -32,7 +32,7 @@ struct SharedHpackHuffmanTable { return base::Singleton<SharedHpackHuffmanTable>::get(); } - scoped_ptr<const HpackHuffmanTable> table; + std::unique_ptr<const HpackHuffmanTable> table; }; // SharedHpackStaticTable is a Singleton wrapping a HpackStaticTable @@ -41,7 +41,7 @@ struct SharedHpackStaticTable { public: SharedHpackStaticTable() { std::vector<HpackStaticEntry> static_table = HpackStaticTableVector(); - scoped_ptr<HpackStaticTable> mutable_table(new HpackStaticTable()); + std::unique_ptr<HpackStaticTable> mutable_table(new HpackStaticTable()); mutable_table->Initialize(&static_table[0], static_table.size()); CHECK(mutable_table->IsInitialized()); table.reset(mutable_table.release()); @@ -51,7 +51,7 @@ struct SharedHpackStaticTable { return base::Singleton<SharedHpackStaticTable>::get(); } - scoped_ptr<const HpackStaticTable> table; + std::unique_ptr<const HpackStaticTable> table; }; } // namespace diff --git a/chromium/net/spdy/hpack/hpack_decoder.cc b/chromium/net/spdy/hpack/hpack_decoder.cc index 6d4ab9896d7..e8f3f263915 100644 --- a/chromium/net/spdy/hpack/hpack_decoder.cc +++ b/chromium/net/spdy/hpack/hpack_decoder.cc @@ -26,15 +26,15 @@ HpackDecoder::HpackDecoder() handler_(nullptr), total_header_bytes_(0), regular_header_seen_(false), - header_block_started_(false) {} + header_block_started_(false), + total_parsed_bytes_(0) {} HpackDecoder::~HpackDecoder() {} bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data, size_t headers_data_length) { - decoded_block_.clear(); if (!header_block_started_) { - header_block_started_ = true; + decoded_block_.clear(); if (handler_ != nullptr) { handler_->OnHeaderBlockStart(); } @@ -45,26 +45,53 @@ bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data, } headers_block_buffer_.insert(headers_block_buffer_.end(), headers_data, headers_data + headers_data_length); - return true; -} -bool HpackDecoder::HandleControlFrameHeadersComplete(size_t* compressed_len) { + // Parse as many data in buffer as possible. And remove the parsed data + // from buffer. HpackInputStream input_stream(max_string_literal_size_, headers_block_buffer_); - regular_header_seen_ = false; - if (compressed_len) { - *compressed_len = headers_block_buffer_.size(); + + // If this is the start of the header block, process table size updates. + if (!header_block_started_) { + if (!DecodeAtMostTwoHeaderTableSizeUpdates(&input_stream)) { + return false; + } + input_stream.MarkCurrentPosition(); } while (input_stream.HasMoreData()) { - if (!DecodeNextOpcode(&input_stream)) { - headers_block_buffer_.clear(); + if (!DecodeNextOpcodeWrapper(&input_stream)) { + if (input_stream.NeedMoreData()) { + break; + } return false; } } + uint32_t parsed_bytes = input_stream.ParsedBytes(); + DCHECK_GE(headers_block_buffer_.size(), parsed_bytes); + headers_block_buffer_.erase(0, parsed_bytes); + total_parsed_bytes_ += parsed_bytes; + header_block_started_ = true; + return true; +} + +bool HpackDecoder::HandleControlFrameHeadersComplete(size_t* compressed_len) { + regular_header_seen_ = false; + + if (compressed_len != nullptr) { + *compressed_len = total_parsed_bytes_; + } + + // Data in headers_block_buffer_ should have been parsed by + // HandleControlFrameHeadersData and removed. + if (headers_block_buffer_.size() > 0) { + return false; + } + if (handler_ != nullptr) { handler_->OnHeaderBlockEnd(total_header_bytes_); } headers_block_buffer_.clear(); + total_parsed_bytes_ = 0; header_block_started_ = false; handler_ = nullptr; return true; @@ -104,6 +131,15 @@ bool HpackDecoder::HandleHeaderRepresentation(StringPiece name, return true; } +bool HpackDecoder::DecodeNextOpcodeWrapper(HpackInputStream* input_stream) { + if (DecodeNextOpcode(input_stream)) { + // Decoding next opcode succeeds. Mark total bytes parsed successfully. + input_stream->MarkCurrentPosition(); + return true; + } + return false; +} + bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) { // Implements 7.1: Indexed Header Field Representation. if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) { @@ -124,12 +160,36 @@ bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) { } // Implements 7.3: Header Table Size Update. if (input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) { - return DecodeNextHeaderTableSizeUpdate(input_stream); + // Header table size updates cannot appear mid-block. + return false; } // Unrecognized opcode. return false; } +// Process 0, 1, or 2 Table Size Updates. +bool HpackDecoder::DecodeAtMostTwoHeaderTableSizeUpdates( + HpackInputStream* input_stream) { + // Implements 7.3: Header Table Size Update. + if (input_stream->HasMoreData() && + input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) { + // One table size update, decode it. + if (DecodeNextHeaderTableSizeUpdate(input_stream)) { + // Check for a second table size update. + if (input_stream->HasMoreData() && + input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) { + // Second update found, return the result of decode. + return DecodeNextHeaderTableSizeUpdate(input_stream); + } + } else { + // Decoding the first table size update failed. + return false; + } + } + // No table size updates in this block. + return true; +} + bool HpackDecoder::DecodeNextHeaderTableSizeUpdate( HpackInputStream* input_stream) { uint32_t size = 0; diff --git a/chromium/net/spdy/hpack/hpack_decoder.h b/chromium/net/spdy/hpack/hpack_decoder.h index b430f7c56ba..778e3082d22 100644 --- a/chromium/net/spdy/hpack/hpack_decoder.h +++ b/chromium/net/spdy/hpack/hpack_decoder.h @@ -112,10 +112,16 @@ class NET_EXPORT_PRIVATE HpackDecoder { // Flag to keep track of having seen the header block start. bool header_block_started_; + // Total bytes have been removed from headers_block_buffer_. + // Its value is updated during incremental decoding. + uint32_t total_parsed_bytes_; + // Handlers for decoding HPACK opcodes and header representations // (or parts thereof). These methods return true on success and // false on error. + bool DecodeNextOpcodeWrapper(HpackInputStream* input_stream); bool DecodeNextOpcode(HpackInputStream* input_stream); + bool DecodeAtMostTwoHeaderTableSizeUpdates(HpackInputStream* input_stream); bool DecodeNextHeaderTableSizeUpdate(HpackInputStream* input_stream); bool DecodeNextIndexedHeader(HpackInputStream* input_stream); bool DecodeNextLiteralHeader(HpackInputStream* input_stream, diff --git a/chromium/net/spdy/hpack/hpack_decoder_test.cc b/chromium/net/spdy/hpack/hpack_decoder_test.cc index e0c49caed8f..9f4c5fb8554 100644 --- a/chromium/net/spdy/hpack/hpack_decoder_test.cc +++ b/chromium/net/spdy/hpack/hpack_decoder_test.cc @@ -37,6 +37,13 @@ class HpackDecoderPeer { const SpdyHeaderBlock& decoded_block() const { return decoder_->decoded_block_; } + + bool DecodeNextStringLiteral(HpackInputStream* in, + bool is_header_key, + StringPiece* str) { + return decoder_->DecodeNextStringLiteral(in, is_header_key, str); + } + const string& headers_block_buffer() const { return decoder_->headers_block_buffer_; } @@ -60,16 +67,26 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool> { protected: HpackDecoderTest() : decoder_(), decoder_peer_(&decoder_) {} + void SetUp() override { handler_exists_ = GetParam(); } + bool DecodeHeaderBlock(StringPiece str) { - if (GetParam()) { + if (handler_exists_) { decoder_.HandleControlFrameHeadersStart(&handler_); } return decoder_.HandleControlFrameHeadersData(str.data(), str.size()) && decoder_.HandleControlFrameHeadersComplete(nullptr); } + bool HandleControlFrameHeadersData(StringPiece str) { + return decoder_.HandleControlFrameHeadersData(str.data(), str.size()); + } + + bool HandleControlFrameHeadersComplete(size_t* size) { + return decoder_.HandleControlFrameHeadersComplete(size); + } + const SpdyHeaderBlock& decoded_block() const { - if (GetParam()) { + if (handler_exists_) { return handler_.decoded_block(); } else { return decoder_peer_.decoded_block(); @@ -95,13 +112,14 @@ class HpackDecoderTest : public ::testing::TestWithParam<bool> { HpackDecoder decoder_; test::HpackDecoderPeer decoder_peer_; TestHeadersHandler handler_; + bool handler_exists_; }; INSTANTIATE_TEST_CASE_P(WithAndWithoutHeadersHandler, HpackDecoderTest, ::testing::Bool()); -TEST_P(HpackDecoderTest, HandleControlFrameHeadersData) { +TEST_P(HpackDecoderTest, AddHeaderDataWithHandleControlFrameHeadersData) { // Strings under threshold are concatenated in the buffer. EXPECT_TRUE(decoder_.HandleControlFrameHeadersData("small string one", 16)); EXPECT_TRUE(decoder_.HandleControlFrameHeadersData("small string two", 16)); @@ -113,8 +131,29 @@ TEST_P(HpackDecoderTest, HandleControlFrameHeadersData) { "small string onesmall string two"); } +// Decode with incomplete data in buffer. +TEST_P(HpackDecoderTest, DecodeWithIncompleteData) { + // No need to wait for more data. + EXPECT_TRUE(HandleControlFrameHeadersData("\x82\x85\x82")); + EXPECT_EQ("", decoder_peer_.headers_block_buffer()); + + // Need to wait for more data. + EXPECT_TRUE( + HandleControlFrameHeadersData("\x40\x03goo" + "\x03gar\xbe\x40\x04spam")); + EXPECT_EQ("\x40\x04spam", decoder_peer_.headers_block_buffer()); + + // Add the needed data. + EXPECT_TRUE(HandleControlFrameHeadersData("\x04gggs")); + EXPECT_EQ("", decoder_peer_.headers_block_buffer()); + + size_t size = 0; + EXPECT_TRUE(HandleControlFrameHeadersComplete(&size)); + EXPECT_EQ(24u, size); +} + TEST_P(HpackDecoderTest, HandleHeaderRepresentation) { - if (GetParam()) { + if (handler_exists_) { decoder_.HandleControlFrameHeadersStart(&handler_); } @@ -165,6 +204,26 @@ TEST_P(HpackDecoderTest, DecodeNextNameLiteral) { EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); EXPECT_EQ("name", string_piece); EXPECT_FALSE(input_stream.HasMoreData()); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(6u, input_stream.ParsedBytes()); +} + +// Decoding an encoded name with an incomplete string literal. +TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHeader) { + HpackInputStream input_stream(kLiteralBound, + StringPiece("\x00\x04name\x00\x02g", 9)); + + StringPiece string_piece; + EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(6u, input_stream.ParsedBytes()); + + EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); + EXPECT_TRUE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(8u, input_stream.ParsedBytes()); } TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) { @@ -175,6 +234,30 @@ TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithHuffmanEncoding) { EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); EXPECT_EQ("custom-key", string_piece); EXPECT_FALSE(input_stream.HasMoreData()); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(input.size(), input_stream.ParsedBytes()); +} + +// Decode with incomplete huffman encoding. +TEST_P(HpackDecoderTest, DecodeNextNameLiteralWithIncompleteHuffmanEncoding) { + // CHECK(huffman_table_.Initialize(kHpackHuffmanCode, + // arraysize(kHpackHuffmanCode))); + // Put two copies of the same huffman encoding into input. + string input = a2b_hex("008825a849e95ba97d7f008825a849e95ba97d7f"); + input.resize(input.size() - 1); // Remove the last byte. + HpackInputStream input_stream(kLiteralBound, input); + + StringPiece string_piece; + EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(10u, input_stream.ParsedBytes()); + + EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); + EXPECT_TRUE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(12u, input_stream.ParsedBytes()); } // Decoding an encoded name with a valid index should work. @@ -185,6 +268,9 @@ TEST_P(HpackDecoderTest, DecodeNextNameIndexed) { EXPECT_TRUE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); EXPECT_EQ(":authority", string_piece); EXPECT_FALSE(input_stream.HasMoreData()); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(1u, input_stream.ParsedBytes()); } // Decoding an encoded name with an invalid index should fail. @@ -194,6 +280,9 @@ TEST_P(HpackDecoderTest, DecodeNextNameInvalidIndex) { StringPiece string_piece; EXPECT_FALSE(decoder_peer_.DecodeNextName(&input_stream, &string_piece)); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(1u, input_stream.ParsedBytes()); } // Decoding indexed static table field should work. @@ -302,6 +391,85 @@ TEST_P(HpackDecoderTest, ContextUpdateMaximumSize) { } } +// Two HeaderTableSizeUpdates may appear at the beginning of the block +TEST_P(HpackDecoderTest, TwoTableSizeUpdates) { + string input; + { + // Should accept two table size updates, update to second one + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(0); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(122); + + output_stream.TakeString(&input); + EXPECT_TRUE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(122u, decoder_peer_.header_table()->max_size()); + } +} + +// Three HeaderTableSizeUpdates should result in an error +TEST_P(HpackDecoderTest, ThreeTableSizeUpdatesError) { + string input; + { + // Should reject three table size updates, update to second one + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(5); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(10); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(15); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(10u, decoder_peer_.header_table()->max_size()); + } +} + +// HeaderTableSizeUpdates may only appear at the beginning of the block +// Any other updates should result in an error +TEST_P(HpackDecoderTest, TableSizeUpdateSecondError) { + string input; + { + // Should reject a table size update appearing after a different entry + // The table size should remain as the default + HpackOutputStream output_stream; + output_stream.AppendBytes("\x82\x85"); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(123); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(kDefaultHeaderTableSizeSetting, + decoder_peer_.header_table()->max_size()); + } +} + +// HeaderTableSizeUpdates may only appear at the beginning of the block +// Any other updates should result in an error +TEST_P(HpackDecoderTest, TableSizeUpdateFirstThirdError) { + string input; + { + // Should reject the second table size update + // if a different entry appears after the first update + // The table size should update to the first but not the second + HpackOutputStream output_stream; + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(60); + output_stream.AppendBytes("\x82\x85"); + output_stream.AppendPrefix(kHeaderTableSizeUpdateOpcode); + output_stream.AppendUint32(125); + + output_stream.TakeString(&input); + + EXPECT_FALSE(DecodeHeaderBlock(StringPiece(input))); + EXPECT_EQ(60u, decoder_peer_.header_table()->max_size()); + } +} + // Decoding two valid encoded literal headers with no indexing should // work. TEST_P(HpackDecoderTest, LiteralHeaderNoIndexing) { @@ -353,6 +521,30 @@ TEST_P(HpackDecoderTest, LiteralHeaderNeverIndexedInvalidNameIndex) { EXPECT_FALSE(DecodeHeaderBlock(StringPiece("\x1f\x2f\x03ooo"))); } +// Decode with incomplete string literal. +TEST_P(HpackDecoderTest, StringLiteralIncomplete) { + const char input[] = "\x0c/sample/path\x06:path2\x0e/sample/path/"; + HpackInputStream input_stream(kLiteralBound, input); + StringPiece str; + EXPECT_TRUE( + decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(13u, input_stream.ParsedBytes()); + + EXPECT_TRUE( + decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); + EXPECT_FALSE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(20u, input_stream.ParsedBytes()); + + EXPECT_FALSE( + decoder_peer_.DecodeNextStringLiteral(&input_stream, false, &str)); + EXPECT_TRUE(input_stream.NeedMoreData()); + input_stream.MarkCurrentPosition(); + EXPECT_EQ(21u, input_stream.ParsedBytes()); +} + // Round-tripping the header set from E.2.1 should work. TEST_P(HpackDecoderTest, BasicE21) { HpackEncoder encoder(ObtainHpackHuffmanTable()); diff --git a/chromium/net/spdy/hpack/hpack_huffman_decoder.cc b/chromium/net/spdy/hpack/hpack_huffman_decoder.cc index 3573744c052..926223f8ad9 100644 --- a/chromium/net/spdy/hpack/hpack_huffman_decoder.cc +++ b/chromium/net/spdy/hpack/hpack_huffman_decoder.cc @@ -158,7 +158,7 @@ const uint8_t kCanonicalToSymbol[] = { }; // clang-format on -#ifndef NDEBUG +#if !defined(NDEBUG) || defined(DCHECK_ALWAYS_ON) // Only used in DLOG. bool IsEOSPrefix(HuffmanWord bits, HuffmanCodeLength bits_available) { @@ -171,7 +171,7 @@ bool IsEOSPrefix(HuffmanWord bits, HuffmanCodeLength bits_available) { return bits == expected; } -#endif // NDEBUG +#endif // NDEBUG && !defined(DCHECK_ALWAYS_ON) } // namespace diff --git a/chromium/net/spdy/hpack/hpack_huffman_table.cc b/chromium/net/spdy/hpack/hpack_huffman_table.cc index e29e1c4debd..8a6b7235570 100644 --- a/chromium/net/spdy/hpack/hpack_huffman_table.cc +++ b/chromium/net/spdy/hpack/hpack_huffman_table.cc @@ -169,7 +169,8 @@ void HpackHuffmanTable::BuildDecodeTables(const std::vector<Symbol>& symbols) { if (entry.length != 0 && entry.length < total_indexed) { // The difference between entry & table bit counts tells us how // many additional entries map to this one. - size_t fill_count = 1 << (total_indexed - entry.length); + size_t fill_count = static_cast<size_t>(1) + << (total_indexed - entry.length); CHECK_LE(j + fill_count, table.size()); for (size_t k = 1; k != fill_count; k++) { diff --git a/chromium/net/spdy/hpack/hpack_input_stream.cc b/chromium/net/spdy/hpack/hpack_input_stream.cc index e9e9540e0ca..79455e51fe7 100644 --- a/chromium/net/spdy/hpack/hpack_input_stream.cc +++ b/chromium/net/spdy/hpack/hpack_input_stream.cc @@ -8,6 +8,7 @@ #include "base/logging.h" #include "net/spdy/hpack/hpack_huffman_decoder.h" +#include "net/spdy/spdy_bug_tracker.h" namespace net { @@ -18,7 +19,10 @@ HpackInputStream::HpackInputStream(uint32_t max_string_literal_size, StringPiece buffer) : max_string_literal_size_(max_string_literal_size), buffer_(buffer), - bit_offset_(0) {} + bit_offset_(0), + parsed_bytes_(0), + parsed_bytes_current_(0), + need_more_data_(false) {} HpackInputStream::~HpackInputStream() {} @@ -27,6 +31,11 @@ bool HpackInputStream::HasMoreData() const { } bool HpackInputStream::MatchPrefixAndConsume(HpackPrefix prefix) { + if (buffer_.empty()) { + need_more_data_ = true; + return false; + } + DCHECK_GT(prefix.bit_size, 0u); DCHECK_LE(prefix.bit_size, 8u); @@ -45,7 +54,11 @@ bool HpackInputStream::MatchPrefixAndConsume(HpackPrefix prefix) { } bool HpackInputStream::PeekNextOctet(uint8_t* next_octet) { - if ((bit_offset_ > 0) || buffer_.empty()) { + if (buffer_.empty()) { + need_more_data_ = true; + return false; + } + if ((bit_offset_ > 0)) { DVLOG(1) << "HpackInputStream::PeekNextOctet bit_offset_=" << bit_offset_; return false; } @@ -60,6 +73,7 @@ bool HpackInputStream::DecodeNextOctet(uint8_t* next_octet) { } buffer_.remove_prefix(1); + parsed_bytes_current_ += 1; return true; } @@ -75,7 +89,9 @@ bool HpackInputStream::DecodeNextUint32(uint32_t* I) { uint8_t next_marker = (1 << N) - 1; uint8_t next_octet = 0; if (!DecodeNextOctet(&next_octet)) { - DVLOG(1) << "HpackInputStream::DecodeNextUint32 initial octet error"; + if (!need_more_data_) { + DVLOG(1) << "HpackInputStream::DecodeNextUint32 initial octet error"; + } return false; } *I = next_octet & next_marker; @@ -85,7 +101,9 @@ bool HpackInputStream::DecodeNextUint32(uint32_t* I) { while (has_more && (shift < 32)) { uint8_t next_octet = 0; if (!DecodeNextOctet(&next_octet)) { - DVLOG(1) << "HpackInputStream::DecodeNextUint32 shift=" << shift; + if (!need_more_data_) { + DVLOG(1) << "HpackInputStream::DecodeNextUint32 shift=" << shift; + } return false; } has_more = (next_octet & 0x80) != 0; @@ -114,23 +132,28 @@ bool HpackInputStream::DecodeNextIdentityString(StringPiece* str) { } if (size > buffer_.size()) { + need_more_data_ = true; return false; } *str = StringPiece(buffer_.data(), size); buffer_.remove_prefix(size); + parsed_bytes_current_ += size; return true; } bool HpackInputStream::DecodeNextHuffmanString(string* str) { uint32_t encoded_size = 0; if (!DecodeNextUint32(&encoded_size)) { - DVLOG(1) << "HpackInputStream::DecodeNextHuffmanString " - << "unable to decode size"; + if (!need_more_data_) { + DVLOG(1) << "HpackInputStream::DecodeNextHuffmanString " + << "unable to decode size"; + } return false; } if (encoded_size > buffer_.size()) { + need_more_data_ = true; DVLOG(1) << "HpackInputStream::DecodeNextHuffmanString " << encoded_size << " > " << buffer_.size(); return false; @@ -139,6 +162,7 @@ bool HpackInputStream::DecodeNextHuffmanString(string* str) { HpackInputStream bounded_reader(max_string_literal_size_, StringPiece(buffer_.data(), encoded_size)); buffer_.remove_prefix(encoded_size); + parsed_bytes_current_ += encoded_size; // DecodeString will not append more than |max_string_literal_size_| chars // to |str|. @@ -200,8 +224,8 @@ std::pair<size_t, uint32_t> HpackInputStream::InitializePeekBits() { break; } } else { - LOG(DFATAL) << "InitializePeekBits called with non-zero bit_offset_: " - << bit_offset_; + SPDY_BUG << "InitializePeekBits called with non-zero bit_offset_: " + << bit_offset_; } return std::make_pair(peeked_count, bits); } @@ -214,6 +238,7 @@ void HpackInputStream::ConsumeBits(size_t bit_count) { CHECK_GT(buffer_.size(), 0u); } buffer_.remove_prefix(byte_count); + parsed_bytes_current_ += byte_count; } void HpackInputStream::ConsumeByteRemainder() { @@ -222,4 +247,16 @@ void HpackInputStream::ConsumeByteRemainder() { } } +uint32_t HpackInputStream::ParsedBytes() const { + return parsed_bytes_; +} + +bool HpackInputStream::NeedMoreData() const { + return need_more_data_; +} + +void HpackInputStream::MarkCurrentPosition() { + parsed_bytes_ = parsed_bytes_current_; +} + } // namespace net diff --git a/chromium/net/spdy/hpack/hpack_input_stream.h b/chromium/net/spdy/hpack/hpack_input_stream.h index ab716d0eff4..b7ec8effa47 100644 --- a/chromium/net/spdy/hpack/hpack_input_stream.h +++ b/chromium/net/spdy/hpack/hpack_input_stream.h @@ -22,12 +22,18 @@ namespace net { +namespace test { +class HpackInputStreamPeer; +} // namespace test + typedef std::pair<size_t, uint32_t> InitialPeekResult; // An HpackInputStream handles all the low-level details of decoding // header fields. class NET_EXPORT_PRIVATE HpackInputStream { public: + friend class test::HpackInputStreamPeer; + // |max_string_literal_size| is the largest that any one string // literal (header name or header value) can be. HpackInputStream(uint32_t max_string_literal_size, base::StringPiece buffer); @@ -72,14 +78,31 @@ class NET_EXPORT_PRIVATE HpackInputStream { // remaining bits in the current byte. void ConsumeByteRemainder(); - // Accessors for testing. + // Return the total bytes that have been parsed SUCCESSFULLY. + uint32_t ParsedBytes() const; + + // When incrementally decode the header, need to remember the current + // position in the buffer after we successfully decode one opcode. + void MarkCurrentPosition(); - void SetBitOffsetForTest(size_t bit_offset) { bit_offset_ = bit_offset; } + // Returning true indicates this instance of HpackInputStream + // doesn't have enough data to parse the current opcode, and we + // are done with this instance. When more data arrive, a new + // HpackInputStream should be created to restart the parsing. + bool NeedMoreData() const; private: const uint32_t max_string_literal_size_; base::StringPiece buffer_; size_t bit_offset_; + // Total number of bytes parsed successfully. Only get updated when an + // opcode is parsed successfully. + uint32_t parsed_bytes_; + // Total number of bytes parsed currently. Get updated when an octet, + // a number or a string has been parsed successfully. Can point to the + // middle of an opcode. + uint32_t parsed_bytes_current_; + bool need_more_data_; bool PeekNextOctet(uint8_t* next_octet); diff --git a/chromium/net/spdy/hpack/hpack_input_stream_test.cc b/chromium/net/spdy/hpack/hpack_input_stream_test.cc index 1b68754080e..a923944a14b 100644 --- a/chromium/net/spdy/hpack/hpack_input_stream_test.cc +++ b/chromium/net/spdy/hpack/hpack_input_stream_test.cc @@ -17,7 +17,7 @@ namespace net { -namespace { +namespace test { using base::StringPiece; using std::string; @@ -35,15 +35,33 @@ const char kEncodedHuffmanFixture[] = const char kDecodedHuffmanFixture[] = "foo=ASDJKHQKBZXOQWEOPIUAXQWEOIU; max-age=3600; version=1"; +class HpackInputStreamPeer { + public: + explicit HpackInputStreamPeer(HpackInputStream* input_stream) + : input_stream_(input_stream) {} + + void SetBitOffsetForTest(size_t bit_offset) { + input_stream_->bit_offset_ = bit_offset; + } + + uint32_t ParsedBytesCurrent() { return input_stream_->parsed_bytes_current_; } + + private: + HpackInputStream* input_stream_; +}; + // Utility function to decode an assumed-valid uint32_t with an N-bit // prefix. uint32_t DecodeValidUint32(uint8_t N, StringPiece str) { EXPECT_GT(N, 0); EXPECT_LE(N, 8); HpackInputStream input_stream(kLiteralBound, str); - input_stream.SetBitOffsetForTest(8 - N); + HpackInputStreamPeer input_stream_peer(&input_stream); + input_stream_peer.SetBitOffsetForTest(8 - N); uint32_t I; EXPECT_TRUE(input_stream.DecodeNextUint32(&I)); + EXPECT_EQ(str.size(), input_stream_peer.ParsedBytesCurrent()); + EXPECT_FALSE(input_stream.NeedMoreData()); return I; } @@ -53,7 +71,8 @@ void ExpectDecodeUint32Invalid(uint8_t N, StringPiece str) { EXPECT_GT(N, 0); EXPECT_LE(N, 8); HpackInputStream input_stream(kLiteralBound, str); - input_stream.SetBitOffsetForTest(8 - N); + HpackInputStreamPeer input_stream_peer(&input_stream); + input_stream_peer.SetBitOffsetForTest(8 - N); uint32_t I; EXPECT_FALSE(input_stream.DecodeNextUint32(&I)); } @@ -478,12 +497,15 @@ TEST(HpackInputStreamTest, SevenByteIntegersOneToSevenBitPrefixes) { // Decoding a valid encoded string literal should work. TEST(HpackInputStreamTest, DecodeNextIdentityString) { HpackInputStream input_stream(kLiteralBound, "\x0estring literal"); + HpackInputStreamPeer input_stream_peer(&input_stream); EXPECT_TRUE(input_stream.HasMoreData()); StringPiece string_piece; EXPECT_TRUE(input_stream.DecodeNextIdentityString(&string_piece)); EXPECT_EQ("string literal", string_piece); EXPECT_FALSE(input_stream.HasMoreData()); + EXPECT_EQ(string_piece.size() + 1, input_stream_peer.ParsedBytesCurrent()); + EXPECT_FALSE(input_stream.NeedMoreData()); } // Decoding an encoded string literal with size larger than @@ -494,6 +516,7 @@ TEST(HpackInputStreamTest, DecodeNextIdentityStringSizeLimit) { EXPECT_TRUE(input_stream.HasMoreData()); StringPiece string_piece; EXPECT_FALSE(input_stream.DecodeNextIdentityString(&string_piece)); + EXPECT_FALSE(input_stream.NeedMoreData()); } // Decoding an encoded string literal with size larger than the @@ -505,16 +528,20 @@ TEST(HpackInputStreamTest, DecodeNextIdentityStringNotEnoughInput) { EXPECT_TRUE(input_stream.HasMoreData()); StringPiece string_piece; EXPECT_FALSE(input_stream.DecodeNextIdentityString(&string_piece)); + EXPECT_TRUE(input_stream.NeedMoreData()); } TEST(HpackInputStreamTest, DecodeNextHuffmanString) { string output, input(a2b_hex(kEncodedHuffmanFixture)); HpackInputStream input_stream(arraysize(kDecodedHuffmanFixture) - 1, input); + HpackInputStreamPeer input_stream_peer(&input_stream); EXPECT_TRUE(input_stream.HasMoreData()); EXPECT_TRUE(input_stream.DecodeNextHuffmanString(&output)); EXPECT_EQ(kDecodedHuffmanFixture, output); EXPECT_FALSE(input_stream.HasMoreData()); + EXPECT_FALSE(input_stream.NeedMoreData()); + EXPECT_EQ(46u, input_stream_peer.ParsedBytesCurrent()); } TEST(HpackInputStreamTest, DecodeNextHuffmanStringSizeLimit) { @@ -525,6 +552,7 @@ TEST(HpackInputStreamTest, DecodeNextHuffmanStringSizeLimit) { // Decoded string overflows the max string literal. EXPECT_TRUE(input_stream.HasMoreData()); EXPECT_FALSE(input_stream.DecodeNextHuffmanString(&output)); + EXPECT_FALSE(input_stream.NeedMoreData()); } TEST(HpackInputStreamTest, DecodeNextHuffmanStringNotEnoughInput) { @@ -535,6 +563,7 @@ TEST(HpackInputStreamTest, DecodeNextHuffmanStringNotEnoughInput) { // Not enough buffer for declared encoded length. EXPECT_TRUE(input_stream.HasMoreData()); EXPECT_FALSE(input_stream.DecodeNextHuffmanString(&output)); + EXPECT_TRUE(input_stream.NeedMoreData()); } TEST(HpackInputStreamTest, PeekBitsAndConsume) { @@ -674,8 +703,8 @@ TEST(HpackInputStreamTest, InitializePeekBits) { bits <<= 28; EXPECT_EQ(0xb0000000, bits); - EXPECT_DFATAL(peeked_count_and_bits = input_stream.InitializePeekBits(), - "bit_offset_"); + EXPECT_SPDY_BUG(peeked_count_and_bits = input_stream.InitializePeekBits(), + "bit_offset_"); EXPECT_EQ(0u, peeked_count_and_bits.first); EXPECT_EQ(0u, peeked_count_and_bits.second); EXPECT_TRUE(input_stream.HasMoreData()); @@ -705,6 +734,75 @@ TEST(HpackInputStreamTest, ConsumeByteRemainder) { EXPECT_FALSE(input_stream.HasMoreData()); } -} // namespace +TEST(HpackInputStreamTest, IncompleteHeaderMatchPrefixAndConsume) { + HpackInputStream input_stream(kLiteralBound, ""); + HpackInputStreamPeer input_stream_peer(&input_stream); + EXPECT_FALSE(input_stream.MatchPrefixAndConsume(kIndexedOpcode)); + EXPECT_EQ(0u, input_stream_peer.ParsedBytesCurrent()); + EXPECT_TRUE(input_stream.NeedMoreData()); +} + +TEST(HpackInputStreamTest, IncompleteHeaderDecodeNextUint32) { + // First byte only + HpackInputStream input_stream1(kLiteralBound, "\xff"); + HpackInputStreamPeer input_stream1_peer(&input_stream1); + EXPECT_TRUE(input_stream1.MatchPrefixAndConsume(kIndexedOpcode)); + uint32_t result; + EXPECT_FALSE(input_stream1.DecodeNextUint32(&result)); + EXPECT_TRUE(input_stream1.NeedMoreData()); + EXPECT_EQ(1u, input_stream1_peer.ParsedBytesCurrent()); + + // No last byte + HpackInputStream input_stream2(kLiteralBound, "\xff\x80\x80\x80"); + HpackInputStreamPeer input_stream2_peer(&input_stream2); + EXPECT_TRUE(input_stream2.MatchPrefixAndConsume(kIndexedOpcode)); + EXPECT_FALSE(input_stream2.DecodeNextUint32(&result)); + EXPECT_TRUE(input_stream2.NeedMoreData()); + EXPECT_EQ(4u, input_stream2_peer.ParsedBytesCurrent()); + + // Error happens before finishing parsing. + HpackInputStream input_stream3(kLiteralBound, "\xff\xff\xff\xff\xff\xff\xff"); + HpackInputStreamPeer input_stream3_peer(&input_stream3); + EXPECT_TRUE(input_stream3.MatchPrefixAndConsume(kIndexedOpcode)); + EXPECT_FALSE(input_stream3.DecodeNextUint32(&result)); + EXPECT_FALSE(input_stream3.NeedMoreData()); + EXPECT_EQ(6u, input_stream3_peer.ParsedBytesCurrent()); +} + +TEST(HpackInputStreamTest, IncompleteHeaderDecodeNextIdentityString) { + HpackInputStream input_stream1(kLiteralBound, "\x0estring litera"); + HpackInputStreamPeer input_stream1_peer(&input_stream1); + StringPiece string_piece; + EXPECT_FALSE(input_stream1.DecodeNextIdentityString(&string_piece)); + // Only parsed first byte. + EXPECT_EQ(1u, input_stream1_peer.ParsedBytesCurrent()); + EXPECT_TRUE(input_stream1.NeedMoreData()); + + HpackInputStream input_stream2(kLiteralBound, "\x0e"); + HpackInputStreamPeer input_stream2_peer(&input_stream2); + EXPECT_FALSE(input_stream2.DecodeNextIdentityString(&string_piece)); + // Only parsed first byte. + EXPECT_EQ(1u, input_stream2_peer.ParsedBytesCurrent()); + EXPECT_TRUE(input_stream2.NeedMoreData()); +} + +TEST(HpackInputStreamTest, IncompleteHeaderDecodeNextHuffmanString) { + string output, input(a2b_hex(kEncodedHuffmanFixture)); + input.resize(input.size() - 1); // Remove last byte. + HpackInputStream input_stream1(arraysize(kDecodedHuffmanFixture) - 1, input); + HpackInputStreamPeer input_stream1_peer(&input_stream1); + EXPECT_FALSE(input_stream1.DecodeNextHuffmanString(&output)); + EXPECT_EQ(1u, input_stream1_peer.ParsedBytesCurrent()); + EXPECT_TRUE(input_stream1.NeedMoreData()); + + input.erase(1, input.size()); // Remove all bytes except the first one. + HpackInputStream input_stream2(arraysize(kDecodedHuffmanFixture) - 1, input); + HpackInputStreamPeer input_stream2_peer(&input_stream2); + EXPECT_FALSE(input_stream2.DecodeNextHuffmanString(&output)); + EXPECT_EQ(1u, input_stream2_peer.ParsedBytesCurrent()); + EXPECT_TRUE(input_stream2.NeedMoreData()); +} + +} // namespace test } // namespace net diff --git a/chromium/net/spdy/http2_write_scheduler.h b/chromium/net/spdy/http2_write_scheduler.h index 2bf5aee0cf5..0a5179ca74f 100644 --- a/chromium/net/spdy/http2_write_scheduler.h +++ b/chromium/net/spdy/http2_write_scheduler.h @@ -11,21 +11,28 @@ #include <cmath> #include <deque> #include <map> +#include <memory> #include <queue> #include <set> #include <unordered_map> #include <utility> #include <vector> -#include "base/containers/hash_tables.h" #include "base/containers/linked_list.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/stl_util.h" +#include "net/spdy/spdy_bug_tracker.h" +#include "net/spdy/spdy_protocol.h" +#include "net/spdy/write_scheduler.h" namespace net { +namespace test { +template <typename StreamIdType> +class Http2PriorityWriteSchedulerPeer; +} + // This data structure implements the HTTP/2 stream priority tree defined in // section 5.3 of RFC 7540: // http://tools.ietf.org/html/rfc7540#section-5.3 @@ -35,105 +42,51 @@ namespace net { // parent stream, and 0 or more child streams. Individual streams can be // marked as ready to read/write, and then the whole structure can be queried // to pick the next stream to read/write out of those that are ready. -// -// The StreamIdType type must be a POD that supports comparison (most -// likely, it will be a number). - -namespace test { -template <typename StreamIdType> -class Http2PriorityWriteSchedulerPeer; -} - -const unsigned int kHttp2RootStreamId = 0; -const int kHttp2DefaultStreamWeight = 16; -const int kHttp2MinStreamWeight = 1; -const int kHttp2MaxStreamWeight = 256; - template <typename StreamIdType> -class Http2PriorityWriteScheduler { +class Http2PriorityWriteScheduler : public WriteScheduler<StreamIdType> { public: Http2PriorityWriteScheduler(); - friend class test::Http2PriorityWriteSchedulerPeer<StreamIdType>; - - // Return the number of streams currently in the tree. - int num_streams() const; - - // Return true if the tree contains a stream with the given ID. - bool StreamRegistered(StreamIdType stream_id) const; - - // Registers a new stream with the given weight and parent, adding it to the - // dependency tree. Non-exclusive streams simply get added below the parent - // stream. If exclusive = true, the stream becomes the parent's sole child - // and the parent's previous children become the children of the new - // stream. If the stream was already registered, logs DFATAL and does - // nothing. If the parent stream is not registered, logs DFATAL and uses the - // root stream as the parent. + // WriteScheduler methods void RegisterStream(StreamIdType stream_id, StreamIdType parent_id, int weight, - bool exclusive); - - // Unregisters the given stream from the scheduler, removing it from the - // dependency tree. If the stream was not previously registered, logs DFATAL - // and does nothing. - void UnregisterStream(StreamIdType stream_id); - - // Returns the weight value for the specified stream. If the stream is not - // registered, logs DFATAL and returns the lowest weight. - int GetStreamWeight(StreamIdType stream_id) const; - - // Returns the stream ID for the parent of the given stream. If the stream - // isn't registered, logs DFATAL and returns the root stream ID (0). - StreamIdType GetStreamParent(StreamIdType stream_id) const; - - // Returns stream IDs of the children of the given stream, if any. If the - // stream isn't registered, logs DFATAL and returns an empty vector. - std::vector<StreamIdType> GetStreamChildren(StreamIdType stream_id) const; - - // Sets the weight of the given stream. If the stream isn't registered or is - // the root stream, logs DFATAL and does nothing. - void SetStreamWeight(StreamIdType stream_id, int weight); - - // Sets the parent of the given stream. If the stream and/or parent aren't - // registered, logs DFATAL and does nothing. If the new parent is a - // descendant of the stream (i.e. this would have created a cycle) then the - // topology of the tree is rearranged as described in section 5.3.3 of RFC - // 7540: https://tools.ietf.org/html/rfc7540#section-5.3.3 - void SetStreamParent(StreamIdType stream_id, - StreamIdType parent_id, - bool exclusive); + bool exclusive) override; + void RegisterStream(StreamIdType stream_id, SpdyPriority priority) override; + void UnregisterStream(StreamIdType stream_id) override; + bool StreamRegistered(StreamIdType stream_id) const override; + SpdyPriority GetStreamPriority(StreamIdType stream_id) const override; + void UpdateStreamPriority(StreamIdType stream_id, + SpdyPriority priority) override; + int GetStreamWeight(StreamIdType stream_id) const override; + void UpdateStreamWeight(StreamIdType stream_id, int weight) override; + StreamIdType GetStreamParent(StreamIdType stream_id) const override; + void UpdateStreamParent(StreamIdType stream_id, + StreamIdType parent_id, + bool exclusive) override; + std::vector<StreamIdType> GetStreamChildren( + StreamIdType stream_id) const override; + void RecordStreamEventTime(StreamIdType stream_id, + int64_t now_in_usec) override; + int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override; + bool ShouldYield(StreamIdType stream_id) const override; + void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override; + void MarkStreamNotReady(StreamIdType stream_id) override; + bool HasReadyStreams() const override; + StreamIdType PopNextReadyStream() override; + size_t NumReadyStreams() const override; // Returns true if the stream parent_id has child_id in its children. If - // either parent or child stream aren't registered, logs DFATAL and returns + // either parent or child stream aren't registered, logs SPDY_BUG and returns // false. bool StreamHasChild(StreamIdType parent_id, StreamIdType child_id) const; - // Marks the stream as blocked or unblocked. If the stream is not registered, - // logs DFATAL and does nothing. - void MarkStreamBlocked(StreamIdType stream_id, bool blocked); - - // Marks the stream as ready or not ready to write; i.e. whether there is - // buffered data for the associated stream. If the stream is not registered, - // logs DFATAL and does nothing. - void MarkStreamReady(StreamIdType stream_id, bool ready); - - // Returns true iff the scheduler has one or more usable streams. A stream is - // usable if it has ready == true and blocked == false, and is not the direct - // or indirect child of another stream that itself has ready == true and - // blocked == false. (Note that the root stream always has ready == false.) - bool HasUsableStreams() const; - - // If the scheduler has any usable streams, returns the ID of the next usable - // stream, in the process changing its ready state to false. If the scheduler - // does not have any usable streams, logs DFATAL and returns the root stream - // ID (0). If there are multiple usable streams, precedence is given to the - // one with the highest priority (thus preserving SPDY priority semantics), - // or, if there are multiple with the highest priority, the one with the - // lowest ordinal (ensuring round-robin ordering). - StreamIdType PopNextUsableStream(); + // Return the number of streams currently in the tree. + int num_streams() const; private: + friend class test::Http2PriorityWriteSchedulerPeer<StreamIdType>; + struct StreamInfo; using StreamInfoVector = std::vector<StreamInfo*>; using StreamInfoMap = std::unordered_map<StreamIdType, StreamInfo*>; @@ -141,7 +94,7 @@ class Http2PriorityWriteScheduler { struct StreamInfo : public base::LinkNode<StreamInfo> { // ID for this stream. StreamIdType id; - // ID of parent stream. + // StreamInfo for parent stream. StreamInfo* parent = nullptr; // Weights can range between 1 and 256 (inclusive). int weight = kHttp2DefaultStreamWeight; @@ -149,23 +102,20 @@ class Http2PriorityWriteScheduler { int total_child_weights = 0; // Pointers to StreamInfos for children, if any. StreamInfoVector children; - // Is the associated stream write-blocked? - bool blocked = false; - // Does the stream have data ready for writing? + // Whether the stream is ready for writing. The stream is present in + // scheduling_queue_ iff true. bool ready = false; - // Whether the stream is currently present in scheduling_queue_. - bool scheduled = false; // The scheduling priority of this stream. Streams with higher priority // values are scheduled first. + // TODO(mpw): rename to avoid confusion with SPDY priorities, + // which this is not. float priority = 0; // Ordinal value for this stream, used to ensure round-robin scheduling: // among streams with the same scheduling priority, streams with lower - // ordinal are scheduled first. The ordinal is reset to a new, greater - // value when the stream is next inserted into scheduling_queue_. + // ordinal are scheduled first. int64_t ordinal = 0; - - // Whether the stream ought to be in scheduling_queue_. - bool IsSchedulable() const { return ready && !blocked; } + // Time of latest write event for stream of this priority, in microseconds. + int64_t last_event_time_usec = 0; // Whether this stream should be scheduled ahead of another stream. bool SchedulesBefore(const StreamInfo& other) const { @@ -177,13 +127,9 @@ class Http2PriorityWriteScheduler { static bool Remove(StreamInfoVector* stream_infos, const StreamInfo* stream_info); - // Clamps weight to a value in [kHttp2MinStreamWeight, - // kHttp2MaxStreamWeight]. - static int ClampWeight(int weight); - // Returns true iff any direct or transitive parent of the given stream is - // currently scheduled. - static bool HasScheduledAncestor(const StreamInfo& stream_info); + // currently ready. + static bool HasReadyAncestor(const StreamInfo& stream_info); // Returns StreamInfo for the given stream, or nullptr if it isn't // registered. @@ -194,13 +140,9 @@ class Http2PriorityWriteScheduler { // including the stream itself. If this results in priority value changes for // scheduled streams, those streams are rescheduled to ensure proper ordering // of scheduling_queue_. + // TODO(mpw): rename to avoid confusion with SPDY priorities. void UpdatePrioritiesUnder(StreamInfo* stream_info); - // Adds or removes stream from scheduling_queue_ according to whether it is - // schedulable. If stream is newly schedulable, assigns it the next - // (increasing) ordinal value. - void UpdateScheduling(StreamInfo* stream_info); - // Inserts stream into scheduling_queue_ at the appropriate location given // its priority and ordinal. Time complexity is O(scheduling_queue.size()). void Schedule(StreamInfo* stream_info); @@ -217,17 +159,20 @@ class Http2PriorityWriteScheduler { // Maps from stream IDs to StreamInfo objects. StreamInfoMap all_stream_infos_; STLValueDeleter<StreamInfoMap> all_stream_infos_deleter_; - // Queue containing all streams that are ready and unblocked, ordered with - // streams of higher priority before streams of lower priority, and, among - // streams of equal priority, streams with lower ordinal before those with - // higher ordinal. Note that not all streams in scheduling_queue_ are - // necessarily usable: some may have ancestor stream(s) that are ready and - // unblocked. In these situations the occluded child streams are left in the - // queue, to reduce churn. + // Queue containing all ready streams, ordered with streams of higher + // priority before streams of lower priority, and, among streams of equal + // priority, streams with lower ordinal before those with higher + // ordinal. Note that not all streams in scheduling_queue_ are eligible to be + // picked as the next stream: some may have ancestor stream(s) that are ready + // and unblocked. In these situations the occluded child streams are left in + // the queue, to reduce churn. base::LinkedList<StreamInfo> scheduling_queue_; - // Ordinal value to assign to next node inserted into - // scheduling_queue_. Incremented after each insertion. - int64_t next_ordinal_ = 0; + // Ordinal value to assign to next node inserted into scheduling_queue_ when + // |add_to_front == true|. Decremented after each assignment. + int64_t head_ordinal_ = -1; + // Ordinal value to assign to next node inserted into scheduling_queue_ when + // |add_to_front == false|. Incremented after each assignment. + int64_t tail_ordinal_ = 0; DISALLOW_COPY_AND_ASSIGN(Http2PriorityWriteScheduler); }; @@ -240,7 +185,7 @@ Http2PriorityWriteScheduler<StreamIdType>::Http2PriorityWriteScheduler() root_stream_info_->weight = kHttp2DefaultStreamWeight; root_stream_info_->parent = nullptr; root_stream_info_->priority = 1.0; - root_stream_info_->ready = true; + root_stream_info_->ready = false; all_stream_infos_[kHttp2RootStreamId] = root_stream_info_; } @@ -262,14 +207,14 @@ void Http2PriorityWriteScheduler<StreamIdType>::RegisterStream( int weight, bool exclusive) { if (StreamRegistered(stream_id)) { - LOG(DFATAL) << "Stream " << stream_id << " already registered"; + SPDY_BUG << "Stream " << stream_id << " already registered"; return; } - weight = ClampWeight(weight); + weight = ClampHttp2Weight(weight); StreamInfo* parent = FindStream(parent_id); if (parent == nullptr) { - LOG(DFATAL) << "Parent stream " << parent_id << " not registered"; + SPDY_BUG << "Parent stream " << parent_id << " not registered"; parent = root_stream_info_; } @@ -300,26 +245,34 @@ void Http2PriorityWriteScheduler<StreamIdType>::RegisterStream( UpdatePrioritiesUnder(parent); // Stream starts with ready == false, so no need to schedule it yet. - DCHECK(!new_stream_info->IsSchedulable()); + DCHECK(!new_stream_info->ready); +} + +template <typename StreamIdType> +void Http2PriorityWriteScheduler<StreamIdType>::RegisterStream( + StreamIdType stream_id, + SpdyPriority priority) { + RegisterStream(stream_id, kHttp2RootStreamId, + SpdyPriorityToHttp2Weight(priority), false); } template <typename StreamIdType> void Http2PriorityWriteScheduler<StreamIdType>::UnregisterStream( StreamIdType stream_id) { if (stream_id == kHttp2RootStreamId) { - LOG(DFATAL) << "Cannot unregister root stream"; + SPDY_BUG << "Cannot unregister root stream"; return; } // Remove the stream from table. typename StreamInfoMap::iterator it = all_stream_infos_.find(stream_id); if (it == all_stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } - scoped_ptr<StreamInfo> stream_info(std::move(it->second)); + std::unique_ptr<StreamInfo> stream_info(std::move(it->second)); all_stream_infos_.erase(it); - // If scheduled, unschedule. - if (stream_info->scheduled) { + // If ready (and hence scheduled), unschedule. + if (stream_info->ready) { Unschedule(stream_info.get()); } @@ -349,11 +302,17 @@ void Http2PriorityWriteScheduler<StreamIdType>::UnregisterStream( } template <typename StreamIdType> +SpdyPriority Http2PriorityWriteScheduler<StreamIdType>::GetStreamPriority( + StreamIdType stream_id) const { + return Http2WeightToSpdyPriority(GetStreamWeight(stream_id)); +} + +template <typename StreamIdType> int Http2PriorityWriteScheduler<StreamIdType>::GetStreamWeight( StreamIdType stream_id) const { const StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return kHttp2MinStreamWeight; } return stream_info->weight; @@ -364,7 +323,7 @@ StreamIdType Http2PriorityWriteScheduler<StreamIdType>::GetStreamParent( StreamIdType stream_id) const { const StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return kHttp2RootStreamId; } if (stream_info->parent == nullptr) { // root stream @@ -379,7 +338,7 @@ std::vector<StreamIdType> Http2PriorityWriteScheduler< std::vector<StreamIdType> child_vec; const StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; } else { child_vec.reserve(stream_info->children.size()); for (StreamInfo* child : stream_info->children) { @@ -390,19 +349,26 @@ std::vector<StreamIdType> Http2PriorityWriteScheduler< } template <typename StreamIdType> -void Http2PriorityWriteScheduler<StreamIdType>::SetStreamWeight( +void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamPriority( + StreamIdType stream_id, + SpdyPriority priority) { + UpdateStreamWeight(stream_id, SpdyPriorityToHttp2Weight(priority)); +} + +template <typename StreamIdType> +void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamWeight( StreamIdType stream_id, int weight) { if (stream_id == kHttp2RootStreamId) { - LOG(DFATAL) << "Cannot set weight of root stream"; + SPDY_BUG << "Cannot set weight of root stream"; return; } StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } - weight = ClampWeight(weight); + weight = ClampHttp2Weight(weight); if (weight == stream_info->weight) { return; } @@ -416,26 +382,26 @@ void Http2PriorityWriteScheduler<StreamIdType>::SetStreamWeight( } template <typename StreamIdType> -void Http2PriorityWriteScheduler<StreamIdType>::SetStreamParent( +void Http2PriorityWriteScheduler<StreamIdType>::UpdateStreamParent( StreamIdType stream_id, StreamIdType parent_id, bool exclusive) { if (stream_id == kHttp2RootStreamId) { - LOG(DFATAL) << "Cannot set parent of root stream"; + SPDY_BUG << "Cannot set parent of root stream"; return; } if (stream_id == parent_id) { - LOG(DFATAL) << "Cannot set stream to be its own parent"; + SPDY_BUG << "Cannot set stream to be its own parent"; return; } StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } StreamInfo* new_parent = FindStream(parent_id); if (new_parent == nullptr) { - LOG(DFATAL) << "Parent stream " << parent_id << " not registered"; + SPDY_BUG << "Parent stream " << parent_id << " not registered"; return; } @@ -458,7 +424,7 @@ void Http2PriorityWriteScheduler<StreamIdType>::SetStreamParent( if (cycle_exists) { // The new parent moves to the level of the current stream. - SetStreamParent(parent_id, stream_info->parent->id, false); + UpdateStreamParent(parent_id, stream_info->parent->id, false); } // Remove stream from old parent's child list. @@ -487,37 +453,112 @@ void Http2PriorityWriteScheduler<StreamIdType>::SetStreamParent( } template <typename StreamIdType> -void Http2PriorityWriteScheduler<StreamIdType>::MarkStreamBlocked( +void Http2PriorityWriteScheduler<StreamIdType>::RecordStreamEventTime( StreamIdType stream_id, - bool blocked) { + int64_t now_in_usec) { if (stream_id == kHttp2RootStreamId) { - LOG(DFATAL) << "Cannot mark root stream blocked or unblocked"; + SPDY_BUG << "Cannot record event time for root stream"; return; } StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } - stream_info->blocked = blocked; - UpdateScheduling(stream_info); + stream_info->last_event_time_usec = now_in_usec; +} + +// O(n) in the number of streams, which isn't great. However, this method will +// soon be superseded by +// Http2WeightedWriteScheduler::GetLatestEventWithPrecedence(), for which an +// efficient implementation is straightforward. Also, this method is only +// called when calculating idle timeouts, so performance isn't key. +template <typename StreamIdType> +int64_t Http2PriorityWriteScheduler<StreamIdType>::GetLatestEventWithPrecedence( + StreamIdType stream_id) const { + if (stream_id == kHttp2RootStreamId) { + SPDY_BUG << "Invalid argument: root stream"; + return 0; + } + const StreamInfo* stream_info = FindStream(stream_id); + if (stream_info == nullptr) { + SPDY_BUG << "Stream " << stream_id << " not registered"; + return 0; + } + int64_t last_event_time_usec = 0; + for (const auto& kv : all_stream_infos_) { + const StreamInfo& other = *kv.second; + if (other.priority > stream_info->priority) { + last_event_time_usec = + std::max(last_event_time_usec, other.last_event_time_usec); + } + } + return last_event_time_usec; +} + +// Worst-case time complexity of O(n*d), where n is scheduling queue length and +// d is tree depth. In practice, should be much shorter, since loop terminates +// at first writable stream or |stream_id| (whichever is first). +template <typename StreamIdType> +bool Http2PriorityWriteScheduler<StreamIdType>::ShouldYield( + StreamIdType stream_id) const { + if (stream_id == kHttp2RootStreamId) { + SPDY_BUG << "Invalid argument: root stream"; + return false; + } + const StreamInfo* stream_info = FindStream(stream_id); + if (stream_info == nullptr) { + SPDY_BUG << "Stream " << stream_id << " not registered"; + return false; + } + for (base::LinkNode<StreamInfo>* s = scheduling_queue_.head(); + s != scheduling_queue_.end(); s = s->next()) { + if (stream_info == s->value()) { + return false; + } + if (!HasReadyAncestor(*s->value())) { + return true; + } + } + return false; } template <typename StreamIdType> void Http2PriorityWriteScheduler<StreamIdType>::MarkStreamReady( StreamIdType stream_id, - bool ready) { + bool add_to_front) { + if (stream_id == kHttp2RootStreamId) { + SPDY_BUG << "Cannot mark root stream ready"; + return; + } + StreamInfo* stream_info = FindStream(stream_id); + if (stream_info == nullptr) { + SPDY_BUG << "Stream " << stream_id << " not registered"; + return; + } + if (stream_info->ready) { + return; + } + stream_info->ordinal = add_to_front ? head_ordinal_-- : tail_ordinal_++; + Schedule(stream_info); +} + +template <typename StreamIdType> +void Http2PriorityWriteScheduler<StreamIdType>::MarkStreamNotReady( + StreamIdType stream_id) { if (stream_id == kHttp2RootStreamId) { - LOG(DFATAL) << "Cannot mark root stream ready or unready"; + SPDY_BUG << "Cannot mark root stream unready"; return; } StreamInfo* stream_info = FindStream(stream_id); if (stream_info == nullptr) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; + return; + } + if (!stream_info->ready) { return; } - stream_info->ready = ready; - UpdateScheduling(stream_info); + Unschedule(stream_info); } template <typename StreamIdType> @@ -535,24 +576,11 @@ bool Http2PriorityWriteScheduler<StreamIdType>::Remove( } template <typename StreamIdType> -int Http2PriorityWriteScheduler<StreamIdType>::ClampWeight(int weight) { - if (weight < kHttp2MinStreamWeight) { - LOG(DFATAL) << "Invalid weight: " << weight; - return kHttp2MinStreamWeight; - } - if (weight > kHttp2MaxStreamWeight) { - LOG(DFATAL) << "Invalid weight: " << weight; - return kHttp2MaxStreamWeight; - } - return weight; -} - -template <typename StreamIdType> -bool Http2PriorityWriteScheduler<StreamIdType>::HasScheduledAncestor( +bool Http2PriorityWriteScheduler<StreamIdType>::HasReadyAncestor( const StreamInfo& stream_info) { for (const StreamInfo* parent = stream_info.parent; parent != nullptr; parent = parent->parent) { - if (parent->scheduled) { + if (parent->ready) { return true; } } @@ -581,7 +609,7 @@ void Http2PriorityWriteScheduler<StreamIdType>::UpdatePrioritiesUnder( child->priority = stream_info->priority * (static_cast<float>(child->weight) / static_cast<float>(stream_info->total_child_weights)); - if (child->scheduled) { + if (child->ready) { // Reposition in scheduling_queue_. Use post-order for scheduling, to // benefit from the fact that children have priority <= parent priority. Unschedule(child); @@ -594,42 +622,27 @@ void Http2PriorityWriteScheduler<StreamIdType>::UpdatePrioritiesUnder( } template <typename StreamIdType> -void Http2PriorityWriteScheduler<StreamIdType>::UpdateScheduling( - StreamInfo* stream_info) { - if (stream_info->IsSchedulable() != stream_info->scheduled) { - if (stream_info->scheduled) { - Unschedule(stream_info); - } else { - stream_info->ordinal = next_ordinal_++; - Schedule(stream_info); - } - } -} - -template <typename StreamIdType> void Http2PriorityWriteScheduler<StreamIdType>::Schedule( StreamInfo* stream_info) { - DCHECK(!stream_info->scheduled); + DCHECK(!stream_info->ready); for (base::LinkNode<StreamInfo>* s = scheduling_queue_.head(); s != scheduling_queue_.end(); s = s->next()) { if (stream_info->SchedulesBefore(*s->value())) { stream_info->InsertBefore(s); - stream_info->scheduled = true; - break; + stream_info->ready = true; + return; } } - if (!stream_info->scheduled) { - stream_info->InsertAfter(scheduling_queue_.tail()); - stream_info->scheduled = true; - } + stream_info->InsertAfter(scheduling_queue_.tail()); + stream_info->ready = true; } template <typename StreamIdType> void Http2PriorityWriteScheduler<StreamIdType>::Unschedule( StreamInfo* stream_info) { - DCHECK(stream_info->scheduled); + DCHECK(stream_info->ready); stream_info->RemoveFromList(); - stream_info->scheduled = false; + stream_info->ready = false; } template <typename StreamIdType> @@ -638,11 +651,11 @@ bool Http2PriorityWriteScheduler<StreamIdType>::StreamHasChild( StreamIdType child_id) const { const StreamInfo* parent = FindStream(parent_id); if (parent == nullptr) { - LOG(DFATAL) << "Parent stream " << parent_id << " not registered"; + SPDY_BUG << "Parent stream " << parent_id << " not registered"; return false; } if (!StreamRegistered(child_id)) { - LOG(DFATAL) << "Child stream " << child_id << " not registered"; + SPDY_BUG << "Child stream " << child_id << " not registered"; return false; } auto found = std::find_if(parent->children.begin(), parent->children.end(), @@ -653,29 +666,34 @@ bool Http2PriorityWriteScheduler<StreamIdType>::StreamHasChild( } template <typename StreamIdType> -bool Http2PriorityWriteScheduler<StreamIdType>::HasUsableStreams() const { - // Even though not every stream in scheduling queue is guaranteed to be - // usable (since children are occluded by parents), the presence of any - // streams guarantees at least one is usable. +bool Http2PriorityWriteScheduler<StreamIdType>::HasReadyStreams() const { return !scheduling_queue_.empty(); } template <typename StreamIdType> -StreamIdType Http2PriorityWriteScheduler<StreamIdType>::PopNextUsableStream() { +StreamIdType Http2PriorityWriteScheduler<StreamIdType>::PopNextReadyStream() { for (base::LinkNode<StreamInfo>* s = scheduling_queue_.head(); s != scheduling_queue_.end(); s = s->next()) { StreamInfo* stream_info = s->value(); - if (!HasScheduledAncestor(*stream_info)) { - stream_info->ready = false; + if (!HasReadyAncestor(*stream_info)) { Unschedule(stream_info); return stream_info->id; } } - LOG(DFATAL) << "No usable streams"; + SPDY_BUG << "No ready streams"; return kHttp2RootStreamId; } template <typename StreamIdType> +size_t Http2PriorityWriteScheduler<StreamIdType>::NumReadyStreams() const { + base::LinkNode<StreamInfo>* node = scheduling_queue_.head(); + size_t size = 0; + while (node != scheduling_queue_.end()) + ++size; + return size; +} + +template <typename StreamIdType> bool Http2PriorityWriteScheduler<StreamIdType>::ValidateInvariantsForTests() const { int total_streams = 0; diff --git a/chromium/net/spdy/http2_write_scheduler_test.cc b/chromium/net/spdy/http2_write_scheduler_test.cc index f581d353263..194bd163246 100644 --- a/chromium/net/spdy/http2_write_scheduler_test.cc +++ b/chromium/net/spdy/http2_write_scheduler_test.cc @@ -4,6 +4,7 @@ #include "net/spdy/http2_write_scheduler.h" +#include "net/spdy/spdy_test_utils.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -62,8 +63,8 @@ TEST_F(Http2PriorityWriteSchedulerTest, RegisterAndUnregisterStreams) { scheduler_.RegisterStream(5, 0, 50, false); // Should not be able to add a stream with an id that already exists. - EXPECT_DFATAL(scheduler_.RegisterStream(5, 1, 50, false), - "Stream 5 already registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(5, 1, 50, false), + "Stream 5 already registered"); EXPECT_EQ(3, scheduler_.num_streams()); EXPECT_TRUE(scheduler_.StreamRegistered(1)); ASSERT_TRUE(scheduler_.StreamRegistered(5)); @@ -80,7 +81,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, RegisterAndUnregisterStreams) { scheduler_.UnregisterStream(5); // Cannot remove a stream that has already been removed. - EXPECT_DFATAL(scheduler_.UnregisterStream(5), "Stream 5 not registered"); + EXPECT_SPDY_BUG(scheduler_.UnregisterStream(5), "Stream 5 not registered"); EXPECT_EQ(3, scheduler_.num_streams()); EXPECT_TRUE(scheduler_.StreamRegistered(1)); EXPECT_FALSE(scheduler_.StreamRegistered(5)); @@ -88,77 +89,108 @@ TEST_F(Http2PriorityWriteSchedulerTest, RegisterAndUnregisterStreams) { EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(13)); // The parent stream 19 doesn't exist, so this should use 0 as parent stream: - EXPECT_DFATAL(scheduler_.RegisterStream(7, 19, 70, false), - "Parent stream 19 not registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(7, 19, 70, false), + "Parent stream 19 not registered"); EXPECT_TRUE(scheduler_.StreamRegistered(7)); EXPECT_EQ(0u, scheduler_.GetStreamParent(7)); // Now stream 7 already exists, so this should fail: - EXPECT_DFATAL(scheduler_.RegisterStream(7, 1, 70, false), - "Stream 7 already registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(7, 1, 70, false), + "Stream 7 already registered"); // Try adding a second child to stream 13: scheduler_.RegisterStream(17, 13, 170, false); // TODO(birenroy): Add a separate test that verifies weight invariants when - // SetStreamWeight is called. - scheduler_.SetStreamWeight(17, 150); + // UpdateStreamWeight is called. + scheduler_.UpdateStreamWeight(17, 150); EXPECT_EQ(150, scheduler_.GetStreamWeight(17)); ASSERT_TRUE(peer_.ValidateInvariants()); } +TEST_F(Http2PriorityWriteSchedulerTest, RegisterStream) { + EXPECT_FALSE(scheduler_.StreamRegistered(1)); + scheduler_.RegisterStream(1, 3); + EXPECT_EQ(0u, scheduler_.NumReadyStreams()); + EXPECT_TRUE(scheduler_.StreamRegistered(1)); + EXPECT_EQ(3, scheduler_.GetStreamPriority(1)); + EXPECT_EQ(SpdyPriorityToHttp2Weight(3), scheduler_.GetStreamWeight(1)); + EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(1)); + EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty()); + + EXPECT_SPDY_BUG(scheduler_.RegisterStream(1, 4), + "Stream 1 already registered"); + EXPECT_EQ(3, scheduler_.GetStreamPriority(1)); +} + TEST_F(Http2PriorityWriteSchedulerTest, GetStreamWeight) { - EXPECT_DFATAL(EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(3)), - "Stream 3 not registered"); + EXPECT_SPDY_BUG( + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(3)), + "Stream 3 not registered"); scheduler_.RegisterStream(3, 0, 130, true); EXPECT_EQ(130, scheduler_.GetStreamWeight(3)); - scheduler_.SetStreamWeight(3, 50); + scheduler_.UpdateStreamWeight(3, 50); EXPECT_EQ(50, scheduler_.GetStreamWeight(3)); scheduler_.UnregisterStream(3); - EXPECT_DFATAL(EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(3)), - "Stream 3 not registered"); + EXPECT_SPDY_BUG( + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(3)), + "Stream 3 not registered"); +} + +TEST_F(Http2PriorityWriteSchedulerTest, GetStreamPriority) { + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), + "Stream 3 not registered"); + scheduler_.RegisterStream(3, 0, 130, true); + EXPECT_EQ(Http2WeightToSpdyPriority(130), scheduler_.GetStreamPriority(3)); + scheduler_.UpdateStreamWeight(3, 50); + EXPECT_EQ(Http2WeightToSpdyPriority(50), scheduler_.GetStreamPriority(3)); + scheduler_.UnregisterStream(3); + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), + "Stream 3 not registered"); } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamParent) { - EXPECT_DFATAL(EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(3)), - "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(3)), + "Stream 3 not registered"); scheduler_.RegisterStream(2, 0, 20, false); scheduler_.RegisterStream(3, 2, 30, false); EXPECT_EQ(2u, scheduler_.GetStreamParent(3)); scheduler_.UnregisterStream(3); - EXPECT_DFATAL(EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(3)), - "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(3)), + "Stream 3 not registered"); } TEST_F(Http2PriorityWriteSchedulerTest, GetStreamChildren) { - EXPECT_DFATAL(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()), - "Stream 7 not registered"); + EXPECT_SPDY_BUG(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()), + "Stream 7 not registered"); scheduler_.RegisterStream(7, 0, 70, false); EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()); scheduler_.RegisterStream(9, 7, 90, false); scheduler_.RegisterStream(15, 7, 150, false); EXPECT_THAT(scheduler_.GetStreamChildren(7), UnorderedElementsAre(9, 15)); scheduler_.UnregisterStream(7); - EXPECT_DFATAL(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()), - "Stream 7 not registered"); + EXPECT_SPDY_BUG(EXPECT_THAT(scheduler_.GetStreamChildren(7), IsEmpty()), + "Stream 7 not registered"); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamWeight) { - EXPECT_DFATAL(scheduler_.SetStreamWeight(0, 10), - "Cannot set weight of root stream"); - EXPECT_DFATAL(scheduler_.SetStreamWeight(3, 10), "Stream 3 not registered"); +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamWeight) { + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(0, 10), + "Cannot set weight of root stream"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 10), + "Stream 3 not registered"); scheduler_.RegisterStream(3, 0, 10, false); - scheduler_.SetStreamWeight(3, 20); + scheduler_.UpdateStreamWeight(3, 20); EXPECT_EQ(20, scheduler_.GetStreamWeight(3)); - EXPECT_DFATAL(scheduler_.SetStreamWeight(3, 500), "Invalid weight: 500"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 500), "Invalid weight: 500"); EXPECT_EQ(kHttp2MaxStreamWeight, scheduler_.GetStreamWeight(3)); - EXPECT_DFATAL(scheduler_.SetStreamWeight(3, 0), "Invalid weight: 0"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 0), "Invalid weight: 0"); EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(3)); scheduler_.UnregisterStream(3); - EXPECT_DFATAL(scheduler_.SetStreamWeight(3, 10), "Stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 10), + "Stream 3 not registered"); } // Basic case of reparenting a subtree. -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicNonExclusive) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentBasicNonExclusive) { /* Tree: 0 / \ @@ -170,7 +202,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicNonExclusive) { scheduler_.RegisterStream(2, 0, 100, false); scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 1, 100, false); - scheduler_.SetStreamParent(1, 2, false); + scheduler_.UpdateStreamParent(1, 2, false); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1)); @@ -181,7 +213,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicNonExclusive) { // Basic case of reparenting a subtree. Result here is the same as the // non-exclusive case. -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicExclusive) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentBasicExclusive) { /* Tree: 0 / \ @@ -193,7 +225,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicExclusive) { scheduler_.RegisterStream(2, 0, 100, false); scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 1, 100, false); - scheduler_.SetStreamParent(1, 2, true); + scheduler_.UpdateStreamParent(1, 2, true); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1)); @@ -204,16 +236,16 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentBasicExclusive) { // We can't set the parent of a nonexistent stream, or set the parent to a // nonexistent stream. -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentNonexistent) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentNonexistent) { scheduler_.RegisterStream(1, 0, 100, false); scheduler_.RegisterStream(2, 0, 100, false); for (bool exclusive : {true, false}) { - EXPECT_DFATAL(scheduler_.SetStreamParent(1, 3, exclusive), - "Parent stream 3 not registered"); - EXPECT_DFATAL(scheduler_.SetStreamParent(4, 2, exclusive), - "Stream 4 not registered"); - EXPECT_DFATAL(scheduler_.SetStreamParent(3, 4, exclusive), - "Stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamParent(1, 3, exclusive), + "Parent stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamParent(4, 2, exclusive), + "Stream 4 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamParent(3, 4, exclusive), + "Stream 3 not registered"); EXPECT_THAT(scheduler_.GetStreamChildren(0), UnorderedElementsAre(1, 2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty()); EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty()); @@ -223,7 +255,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentNonexistent) { // We should be able to add multiple children to streams. TEST_F(Http2PriorityWriteSchedulerTest, - SetStreamParentMultipleChildrenNonExclusive) { + UpdateStreamParentMultipleChildrenNonExclusive) { /* Tree: 0 / \ @@ -236,7 +268,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 1, 100, false); scheduler_.RegisterStream(5, 2, 100, false); - scheduler_.SetStreamParent(2, 1, false); + scheduler_.UpdateStreamParent(2, 1, false); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3, 4)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5)); @@ -247,7 +279,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, } TEST_F(Http2PriorityWriteSchedulerTest, - SetStreamParentMultipleChildrenExclusive) { + UpdateStreamParentMultipleChildrenExclusive) { /* Tree: 0 / \ @@ -260,7 +292,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 1, 100, false); scheduler_.RegisterStream(5, 2, 100, false); - scheduler_.SetStreamParent(2, 1, true); + scheduler_.UpdateStreamParent(2, 1, true); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1)); EXPECT_THAT(scheduler_.GetStreamChildren(1), ElementsAre(2)); EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(3, 4, 5)); @@ -270,7 +302,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildNonExclusive) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToChildNonExclusive) { /* Tree: 0 | @@ -284,7 +316,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildNonExclusive) { scheduler_.RegisterStream(2, 1, 100, false); scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 2, 100, false); - scheduler_.SetStreamParent(1, 2, false); + scheduler_.UpdateStreamParent(1, 2, false); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), ElementsAre(3)); EXPECT_THAT(scheduler_.GetStreamChildren(2), UnorderedElementsAre(1, 4)); @@ -293,7 +325,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildNonExclusive) { ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildExclusive) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToChildExclusive) { /* Tree: 0 | @@ -307,7 +339,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildExclusive) { scheduler_.RegisterStream(2, 1, 100, false); scheduler_.RegisterStream(3, 1, 100, false); scheduler_.RegisterStream(4, 2, 100, false); - scheduler_.SetStreamParent(1, 2, true); + scheduler_.UpdateStreamParent(1, 2, true); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(2)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(3, 4)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(1)); @@ -317,7 +349,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToChildExclusive) { } TEST_F(Http2PriorityWriteSchedulerTest, - SetStreamParentToGrandchildNonExclusive) { + UpdateStreamParentToGrandchildNonExclusive) { /* Tree: 0 | @@ -335,7 +367,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, scheduler_.RegisterStream(4, 2, 100, false); scheduler_.RegisterStream(5, 2, 100, false); scheduler_.RegisterStream(6, 4, 100, false); - scheduler_.SetStreamParent(1, 4, false); + scheduler_.UpdateStreamParent(1, 4, false); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5)); @@ -346,7 +378,8 @@ TEST_F(Http2PriorityWriteSchedulerTest, ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToGrandchildExclusive) { +TEST_F(Http2PriorityWriteSchedulerTest, + UpdateStreamParentToGrandchildExclusive) { /* Tree: 0 | @@ -364,7 +397,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToGrandchildExclusive) { scheduler_.RegisterStream(4, 2, 100, false); scheduler_.RegisterStream(5, 2, 100, false); scheduler_.RegisterStream(6, 4, 100, false); - scheduler_.SetStreamParent(1, 4, true); + scheduler_.UpdateStreamParent(1, 4, true); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(4)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3, 6)); EXPECT_THAT(scheduler_.GetStreamChildren(2), ElementsAre(5)); @@ -375,12 +408,12 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToGrandchildExclusive) { ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToParent) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToParent) { scheduler_.RegisterStream(1, 0, 100, false); scheduler_.RegisterStream(2, 1, 100, false); scheduler_.RegisterStream(3, 1, 100, false); for (bool exclusive : {true, false}) { - scheduler_.SetStreamParent(2, 1, exclusive); + scheduler_.UpdateStreamParent(2, 1, exclusive); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1)); EXPECT_THAT(scheduler_.GetStreamChildren(1), UnorderedElementsAre(2, 3)); EXPECT_THAT(scheduler_.GetStreamChildren(2), IsEmpty()); @@ -389,12 +422,12 @@ TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToParent) { ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, SetStreamParentToSelf) { +TEST_F(Http2PriorityWriteSchedulerTest, UpdateStreamParentToSelf) { scheduler_.RegisterStream(1, 0, 100, false); - EXPECT_DFATAL(scheduler_.SetStreamParent(1, 1, false), - "Cannot set stream to be its own parent"); - EXPECT_DFATAL(scheduler_.SetStreamParent(1, 1, true), - "Cannot set stream to be its own parent"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamParent(1, 1, false), + "Cannot set stream to be its own parent"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamParent(1, 1, true), + "Cannot set stream to be its own parent"); EXPECT_THAT(scheduler_.GetStreamChildren(0), ElementsAre(1)); EXPECT_THAT(scheduler_.GetStreamChildren(1), IsEmpty()); ASSERT_TRUE(peer_.ValidateInvariants()); @@ -404,10 +437,10 @@ TEST_F(Http2PriorityWriteSchedulerTest, StreamHasChild) { scheduler_.RegisterStream(1, 0, 10, false); scheduler_.RegisterStream(2, 1, 20, false); scheduler_.RegisterStream(3, 1, 30, false); - EXPECT_DFATAL(EXPECT_FALSE(scheduler_.StreamHasChild(4, 1)), - "Parent stream 4 not registered"); - EXPECT_DFATAL(EXPECT_FALSE(scheduler_.StreamHasChild(3, 7)), - "Child stream 7 not registered"); + EXPECT_SPDY_BUG(EXPECT_FALSE(scheduler_.StreamHasChild(4, 1)), + "Parent stream 4 not registered"); + EXPECT_SPDY_BUG(EXPECT_FALSE(scheduler_.StreamHasChild(3, 7)), + "Child stream 7 not registered"); EXPECT_FALSE(scheduler_.StreamHasChild(3, 1)); EXPECT_TRUE(scheduler_.StreamHasChild(1, 3)); EXPECT_TRUE(scheduler_.StreamHasChild(1, 2)); @@ -445,7 +478,7 @@ TEST_F(Http2PriorityWriteSchedulerTest, BlockAndUnblock) { scheduler_.RegisterStream(7, 0, 100, false); scheduler_.RegisterStream(13, 7, 100, true); scheduler_.RegisterStream(14, 7, 100, false); - scheduler_.SetStreamParent(7, 3, false); + scheduler_.UpdateStreamParent(7, 3, false); EXPECT_EQ(0u, scheduler_.GetStreamParent(1)); EXPECT_EQ(0u, scheduler_.GetStreamParent(2)); EXPECT_EQ(0u, scheduler_.GetStreamParent(3)); @@ -476,22 +509,18 @@ TEST_F(Http2PriorityWriteSchedulerTest, BlockAndUnblock) { ASSERT_TRUE(peer_.ValidateInvariants()); } -TEST_F(Http2PriorityWriteSchedulerTest, HasUsableStreams) { - EXPECT_FALSE(scheduler_.HasUsableStreams()); +TEST_F(Http2PriorityWriteSchedulerTest, HasReadyStreams) { + EXPECT_FALSE(scheduler_.HasReadyStreams()); scheduler_.RegisterStream(1, 0, 10, false); - EXPECT_FALSE(scheduler_.HasUsableStreams()); - scheduler_.MarkStreamReady(1, true); - EXPECT_TRUE(scheduler_.HasUsableStreams()); - scheduler_.MarkStreamBlocked(1, true); - EXPECT_FALSE(scheduler_.HasUsableStreams()); + EXPECT_FALSE(scheduler_.HasReadyStreams()); scheduler_.MarkStreamReady(1, false); - EXPECT_FALSE(scheduler_.HasUsableStreams()); - scheduler_.MarkStreamBlocked(1, false); - EXPECT_FALSE(scheduler_.HasUsableStreams()); + EXPECT_TRUE(scheduler_.HasReadyStreams()); + scheduler_.MarkStreamNotReady(1); + EXPECT_FALSE(scheduler_.HasReadyStreams()); scheduler_.MarkStreamReady(1, true); - EXPECT_TRUE(scheduler_.HasUsableStreams()); + EXPECT_TRUE(scheduler_.HasReadyStreams()); scheduler_.UnregisterStream(1); - EXPECT_FALSE(scheduler_.HasUsableStreams()); + EXPECT_FALSE(scheduler_.HasReadyStreams()); ASSERT_TRUE(peer_.ValidateInvariants()); } @@ -529,7 +558,53 @@ TEST_F(Http2PriorityWriteSchedulerTest, CalculateRoundedWeights) { ASSERT_TRUE(peer_.ValidateInvariants()); } -class PopNextUsableStreamTest : public Http2PriorityWriteSchedulerTest { +TEST_F(Http2PriorityWriteSchedulerTest, GetLatestEventWithPrecedence) { + EXPECT_SPDY_BUG(scheduler_.RecordStreamEventTime(3, 5), + "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(4)), + "Stream 4 not registered"); + + for (int i = 1; i < 5; ++i) { + scheduler_.RegisterStream(i, 0, SpdyPriorityToHttp2Weight(i), false); + } + for (int i = 1; i < 5; ++i) { + EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(i)); + } + for (int i = 1; i < 5; ++i) { + scheduler_.RecordStreamEventTime(i, i * 100); + } + for (int i = 1; i < 5; ++i) { + EXPECT_EQ((i - 1) * 100, scheduler_.GetLatestEventWithPrecedence(i)); + } +} + +// Add ready streams at front and back. +TEST_F(Http2PriorityWriteSchedulerTest, MarkReadyFrontAndBack) { + scheduler_.RegisterStream(1, 0, 10, false); + scheduler_.RegisterStream(2, 0, 20, false); + scheduler_.RegisterStream(3, 0, 20, false); + scheduler_.RegisterStream(4, 0, 20, false); + scheduler_.RegisterStream(5, 0, 30, false); + + for (int i = 1; i < 6; ++i) { + scheduler_.MarkStreamReady(i, false); + } + EXPECT_EQ(5u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + scheduler_.MarkStreamReady(2, false); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + scheduler_.MarkStreamReady(3, false); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + scheduler_.MarkStreamReady(4, false); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + scheduler_.MarkStreamReady(2, true); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + scheduler_.MarkStreamReady(5, false); + scheduler_.MarkStreamReady(2, true); + EXPECT_EQ(5u, scheduler_.PopNextReadyStream()); +} + +class PopNextReadyStreamTest : public Http2PriorityWriteSchedulerTest { protected: void SetUp() override { /* Create the tree. @@ -554,7 +629,7 @@ class PopNextUsableStreamTest : public Http2PriorityWriteSchedulerTest { // Set all nodes ready to write. for (SpdyStreamId id = 1; id <= 8; ++id) { - scheduler_.MarkStreamReady(id, true); + scheduler_.MarkStreamReady(id, false); } } @@ -564,8 +639,8 @@ class PopNextUsableStreamTest : public Http2PriorityWriteSchedulerTest { const int kNumCyclesToCheck = 2; for (int i = 0; i < kNumCyclesToCheck; i++) { for (SpdyStreamId expected_id : stream_ids) { - SpdyStreamId next_id = scheduler_.PopNextUsableStream(); - scheduler_.MarkStreamReady(next_id, true); + SpdyStreamId next_id = scheduler_.PopNextReadyStream(); + scheduler_.MarkStreamReady(next_id, false); if (next_id != expected_id) { return AssertionFailure() << "Pick " << count << ": expected stream " << expected_id << " instead of " << next_id; @@ -581,39 +656,39 @@ class PopNextUsableStreamTest : public Http2PriorityWriteSchedulerTest { }; // When all streams are schedulable, only top-level streams should be returned. -TEST_F(PopNextUsableStreamTest, NoneBlocked) { +TEST_F(PopNextReadyStreamTest, NoneBlocked) { EXPECT_TRUE(PopNextReturnsCycle({1, 2, 3})); } // When a parent stream is blocked, its children should be scheduled, if // priorities allow. -TEST_F(PopNextUsableStreamTest, SingleStreamBlocked) { - scheduler_.MarkStreamReady(1, false); +TEST_F(PopNextReadyStreamTest, SingleStreamBlocked) { + scheduler_.MarkStreamNotReady(1); // Round-robin only across 2 and 3, since children of 1 have lower priority. EXPECT_TRUE(PopNextReturnsCycle({2, 3})); // Make children of 1 have equal priority as 2 and 3, after which they should // be returned as well. - scheduler_.SetStreamWeight(1, 200); + scheduler_.UpdateStreamWeight(1, 200); EXPECT_TRUE(PopNextReturnsCycle({4, 5, 2, 3})); } // Block multiple levels of streams. -TEST_F(PopNextUsableStreamTest, MultiLevelBlocked) { +TEST_F(PopNextReadyStreamTest, MultiLevelBlocked) { for (SpdyStreamId stream_id : {1, 4, 5}) { - scheduler_.MarkStreamReady(stream_id, false); + scheduler_.MarkStreamNotReady(stream_id); } // Round-robin only across 2 and 3, since children of 1 have lower priority. EXPECT_TRUE(PopNextReturnsCycle({2, 3})); // Make 8 have equal priority as 2 and 3. - scheduler_.SetStreamWeight(1, 200); + scheduler_.UpdateStreamWeight(1, 200); EXPECT_TRUE(PopNextReturnsCycle({8, 2, 3})); } // A removed stream shouldn't be scheduled. -TEST_F(PopNextUsableStreamTest, RemoveStream) { +TEST_F(PopNextReadyStreamTest, RemoveStream) { scheduler_.UnregisterStream(1); // Round-robin only across 2 and 3, since previous children of 1 have lower @@ -622,52 +697,52 @@ TEST_F(PopNextUsableStreamTest, RemoveStream) { EXPECT_TRUE(PopNextReturnsCycle({2, 3})); // Make previous children of 1 have equal priority as 2 and 3. - scheduler_.SetStreamWeight(4, 100); - scheduler_.SetStreamWeight(5, 100); + scheduler_.UpdateStreamWeight(4, 100); + scheduler_.UpdateStreamWeight(5, 100); EXPECT_TRUE(PopNextReturnsCycle({4, 5, 2, 3})); } // Block an entire subtree. -TEST_F(PopNextUsableStreamTest, SubtreeBlocked) { +TEST_F(PopNextReadyStreamTest, SubtreeBlocked) { for (SpdyStreamId stream_id : {1, 4, 5, 8}) { - scheduler_.MarkStreamReady(stream_id, false); + scheduler_.MarkStreamNotReady(stream_id); } EXPECT_TRUE(PopNextReturnsCycle({2, 3})); } // If all parent streams are blocked, children should be returned. -TEST_F(PopNextUsableStreamTest, ParentsBlocked) { +TEST_F(PopNextReadyStreamTest, ParentsBlocked) { for (SpdyStreamId stream_id : {1, 2, 3}) { - scheduler_.MarkStreamReady(stream_id, false); + scheduler_.MarkStreamNotReady(stream_id); } EXPECT_TRUE(PopNextReturnsCycle({4, 5, 6, 7})); } // Unblocking streams should make them schedulable. -TEST_F(PopNextUsableStreamTest, BlockAndUnblock) { +TEST_F(PopNextReadyStreamTest, BlockAndUnblock) { EXPECT_TRUE(PopNextReturnsCycle({1, 2, 3})); - scheduler_.MarkStreamReady(2, false); + scheduler_.MarkStreamNotReady(2); EXPECT_TRUE(PopNextReturnsCycle({1, 3})); - scheduler_.MarkStreamReady(2, true); + scheduler_.MarkStreamReady(2, false); // Cycle order permuted since 2 effectively appended at tail. EXPECT_TRUE(PopNextReturnsCycle({1, 3, 2})); } // Block nodes in multiple subtrees. -TEST_F(PopNextUsableStreamTest, ScatteredBlocked) { +TEST_F(PopNextReadyStreamTest, ScatteredBlocked) { for (SpdyStreamId stream_id : {1, 2, 6, 7}) { - scheduler_.MarkStreamReady(stream_id, false); + scheduler_.MarkStreamNotReady(stream_id); } // Only 3 returned, since of remaining streams it has highest priority. EXPECT_TRUE(PopNextReturnsCycle({3})); // Make children of 1 have priority equal to 3. - scheduler_.SetStreamWeight(1, 200); + scheduler_.UpdateStreamWeight(1, 200); EXPECT_TRUE(PopNextReturnsCycle({4, 5, 3})); // When 4 is blocked, its child 8 should take its place, since it has same // priority. - scheduler_.MarkStreamReady(4, false); + scheduler_.MarkStreamNotReady(4); EXPECT_TRUE(PopNextReturnsCycle({8, 5, 3})); } diff --git a/chromium/net/spdy/mock_spdy_framer_visitor.h b/chromium/net/spdy/mock_spdy_framer_visitor.h index d330c262b25..ac97a3dbb81 100644 --- a/chromium/net/spdy/mock_spdy_framer_visitor.h +++ b/chromium/net/spdy/mock_spdy_framer_visitor.h @@ -24,10 +24,8 @@ class MockSpdyFramerVisitor : public SpdyFramerVisitorInterface { MOCK_METHOD3(OnDataFrameHeader, void(SpdyStreamId stream_id, size_t length, bool fin)); - MOCK_METHOD4(OnStreamFrameData, void(SpdyStreamId stream_id, - const char* data, - size_t len, - bool fin)); + MOCK_METHOD3(OnStreamFrameData, + void(SpdyStreamId stream_id, const char* data, size_t len)); MOCK_METHOD1(OnStreamEnd, void(SpdyStreamId stream_id)); MOCK_METHOD2(OnStreamPadding, void(SpdyStreamId stream_id, size_t len)); MOCK_METHOD1(OnHeaderFrameStart, diff --git a/chromium/net/spdy/priority_write_scheduler.h b/chromium/net/spdy/priority_write_scheduler.h index e1e144dd96c..80dd5c4fef0 100644 --- a/chromium/net/spdy/priority_write_scheduler.h +++ b/chromium/net/spdy/priority_write_scheduler.h @@ -6,91 +6,95 @@ #define NET_SPDY_PRIORITY_WRITE_SCHEDULER_H_ #include <stddef.h> +#include <stdint.h> #include <algorithm> #include <deque> #include <unordered_map> #include <utility> +#include <vector> #include "base/logging.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_protocol.h" +#include "net/spdy/write_scheduler.h" namespace net { -// Class that manages the order in which streams are written using the SPDY -// priority scheme described at: +namespace test { +template <typename StreamIdType> +class PriorityWriteSchedulerPeer; +} + +// WriteScheduler implementation that manages the order in which streams are +// written using the SPDY priority scheme described at: // https://www.chromium.org/spdy/spdy-protocol/spdy-protocol-draft3-1#TOC-2.3.3-Stream-priority // -// Callers must first register a stream with the PriorityWriteScheduler (by -// calling RegisterStream(), which informs the PriorityWriteScheduler of the -// stream's priority) before calling other methods referencing that stream, -// which may implicitly use the stream's priority. When the stream is -// eventually closed, the caller should unregister it from the -// PriorityWriteScheduler (by calling UnregisterStream()), to free data -// structures associated with it. -// -// Each stream can be in one of two states: ready or not ready (for writing). -// Ready state is changed by calling the MarkStreamReady() and -// MarkStreamNotReady() methods. Only streams in the ready state can be -// returned by PopNextReadyStream(); when returned by that method, the stream's -// state changes to not ready. -// -// Internally, PriorityWriteScheduler consists of 8 per-priority sublists, one -// for each priority value. The elements (if any) of each sublist are streams -// that are ready to write and have that priority. +// Internally, PriorityWriteScheduler consists of 8 PriorityInfo objects, one +// for each priority value. Each PriorityInfo contains a list of streams of +// that priority that are ready to write, as well as a timestamp of the last +// I/O event that occurred for a stream of that priority. template <typename StreamIdType> -class PriorityWriteScheduler { +class PriorityWriteScheduler : public WriteScheduler<StreamIdType> { public: // Creates scheduler with no streams. PriorityWriteScheduler() = default; - // Registers the given stream with the scheduler, which will now track its - // priority and ready state. If the stream was already registered, logs - // DFATAL and does nothing. - void RegisterStream(StreamIdType stream_id, SpdyPriority priority) { - priority = ClampPriority(priority); + void RegisterStream(StreamIdType stream_id, + StreamIdType parent_id, + int weight, + bool exclusive) override { + // parent_id not used here, but may as well validate it + SPDY_BUG_IF(parent_id != kHttp2RootStreamId && !StreamRegistered(parent_id)) + << "Stream " << parent_id << " not registered"; + RegisterStream(stream_id, Http2WeightToSpdyPriority(weight)); + } + + void RegisterStream(StreamIdType stream_id, SpdyPriority priority) override { + if (stream_id == kHttp2RootStreamId) { + SPDY_BUG << "Stream " << kHttp2RootStreamId << " already registered"; + return; + } + priority = ClampSpdyPriority(priority); StreamInfo stream_info = {priority, false}; bool inserted = stream_infos_.insert(std::make_pair(stream_id, stream_info)).second; - if (!inserted) { - LOG(DFATAL) << "Stream " << stream_id << " already registered"; - } + SPDY_BUG_IF(!inserted) << "Stream " << stream_id << " already registered"; } - // Unregisters the given stream from the scheduler, which will no - // longer keep track of its priority and ready state. If the stream - // was not previously registered, logs DFATAL and does nothing. - void UnregisterStream(StreamIdType stream_id) { + void UnregisterStream(StreamIdType stream_id) override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } StreamInfo& stream_info = it->second; if (stream_info.ready) { - bool erased = Erase(&ready_lists_[stream_info.priority], stream_id); + bool erased = + Erase(&priority_infos_[stream_info.priority].ready_list, stream_id); DCHECK(erased); } stream_infos_.erase(it); } - // Returns the priority value for the specified stream. If the stream is not - // registered, logs DFATAL and returns the lowest priority. - SpdyPriority GetStreamPriority(StreamIdType stream_id) const { + bool StreamRegistered(StreamIdType stream_id) const override { + return stream_infos_.find(stream_id) != stream_infos_.end(); + } + + SpdyPriority GetStreamPriority(StreamIdType stream_id) const override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return kV3LowestPriority; } return it->second.priority; } - // Updates the priority of the given stream. If the stream is not registered, - // logs DFATAL and does nothing. - void UpdateStreamPriority(StreamIdType stream_id, SpdyPriority priority) { + void UpdateStreamPriority(StreamIdType stream_id, + SpdyPriority priority) override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } StreamInfo& stream_info = it->second; @@ -98,56 +102,101 @@ class PriorityWriteScheduler { return; } if (stream_info.ready) { - bool erased = Erase(&ready_lists_[stream_info.priority], stream_id); + bool erased = + Erase(&priority_infos_[stream_info.priority].ready_list, stream_id); DCHECK(erased); - ready_lists_[priority].push_back(stream_id); + priority_infos_[priority].ready_list.push_back(stream_id); } stream_info.priority = priority; } - // If the scheduler has any ready streams, pops the next stream ID from the - // highest priority non-empty ready list and returns it, transitioning the - // stream from ready to not ready. If the scheduler doesn't have any ready - // streams, logs DFATAL and returns 0. - StreamIdType PopNextReadyStream() { + int GetStreamWeight(StreamIdType stream_id) const override { + return SpdyPriorityToHttp2Weight(GetStreamPriority(stream_id)); + } + + void UpdateStreamWeight(StreamIdType stream_id, int weight) override { + UpdateStreamPriority(stream_id, Http2WeightToSpdyPriority(weight)); + } + + StreamIdType GetStreamParent(StreamIdType stream_id) const override { + return kHttp2RootStreamId; + } + + void UpdateStreamParent(StreamIdType stream_id, + StreamIdType parent_id, + bool exclusive) override {} + + std::vector<StreamIdType> GetStreamChildren( + StreamIdType stream_id) const override { + return std::vector<StreamIdType>(); + } + + void RecordStreamEventTime(StreamIdType stream_id, + int64_t now_in_usec) override { + auto it = stream_infos_.find(stream_id); + if (it == stream_infos_.end()) { + SPDY_BUG << "Stream " << stream_id << " not registered"; + return; + } + PriorityInfo& priority_info = priority_infos_[it->second.priority]; + priority_info.last_event_time_usec = + std::max(priority_info.last_event_time_usec, now_in_usec); + } + + int64_t GetLatestEventWithPrecedence(StreamIdType stream_id) const override { + auto it = stream_infos_.find(stream_id); + if (it == stream_infos_.end()) { + SPDY_BUG << "Stream " << stream_id << " not registered"; + return 0; + } + int64_t last_event_time_usec = 0; + const StreamInfo& stream_info = it->second; + for (SpdyPriority p = kV3HighestPriority; p < stream_info.priority; ++p) { + last_event_time_usec = std::max(last_event_time_usec, + priority_infos_[p].last_event_time_usec); + } + return last_event_time_usec; + } + + StreamIdType PopNextReadyStream() override { StreamIdType stream_id = 0; for (SpdyPriority p = kV3HighestPriority; p <= kV3LowestPriority; ++p) { - StreamIdList& ready_list = ready_lists_[p]; + StreamIdList& ready_list = priority_infos_[p].ready_list; if (!ready_list.empty()) { stream_id = ready_list.front(); ready_list.pop_front(); auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Missing StreamInfo for stream " << stream_id; + SPDY_BUG << "Missing StreamInfo for stream " << stream_id; } else { it->second.ready = false; } return stream_id; } } - LOG(DFATAL) << "No ready streams available"; + SPDY_BUG << "No ready streams available"; return stream_id; } - // Returns true if there's another stream of greater or equal priority ahead - // of |stream_id| in the queue. This function can be called to see if - // |stream_id| should yield work to another stream. - bool ShouldYield(StreamIdType stream_id) const { - // If there's a higher priority stream, this stream should yield. - if (HasHigherPriorityReadyStream(stream_id)) { - return true; - } - + bool ShouldYield(StreamIdType stream_id) const override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return false; } + // If there's a higher priority stream, this stream should yield. + const StreamInfo& stream_info = it->second; + for (SpdyPriority p = kV3HighestPriority; p < stream_info.priority; ++p) { + if (!priority_infos_[p].ready_list.empty()) { + return true; + } + } + // If this priority level is empty, or this stream is the next up, there's // no need to yield. - auto ready_list = ready_lists_[it->second.priority]; + auto ready_list = priority_infos_[it->second.priority].ready_list; if (ready_list.empty() || ready_list.front() == stream_id) { return false; } @@ -157,39 +206,17 @@ class PriorityWriteScheduler { return true; } - // Returns true if the scheduler has any ready streams with a higher priority - // than that of the specified stream. If the stream is not registered, logs - // DFATAL and returns false. - bool HasHigherPriorityReadyStream(StreamIdType stream_id) const { + void MarkStreamReady(StreamIdType stream_id, bool add_to_front) override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; - return false; - } - const StreamInfo& stream_info = it->second; - for (SpdyPriority p = kV3HighestPriority; p < stream_info.priority; ++p) { - if (!ready_lists_[p].empty()) { - return true; - } - } - return false; - } - - // Marks the given stream as ready to write. If stream was already ready, - // does nothing. If stream was not registered, logs DFATAL and does - // nothing. If |add_to_front| is true, adds stream to the front of its - // per-priority ready list, otherwise adds it to the back. - void MarkStreamReady(StreamIdType stream_id, bool add_to_front) { - auto it = stream_infos_.find(stream_id); - if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } StreamInfo& stream_info = it->second; if (stream_info.ready) { return; } - StreamIdList& ready_list = ready_lists_[stream_info.priority]; + StreamIdList& ready_list = priority_infos_[stream_info.priority].ready_list; if (add_to_front) { ready_list.push_front(stream_id); } else { @@ -198,28 +225,26 @@ class PriorityWriteScheduler { stream_info.ready = true; } - // Marks the given stream as not ready to write, removing it from the ready - // list for its priority. If stream was already not ready, does nothing. If - // stream was not registered, logs DFATAL and does nothing. - void MarkStreamNotReady(StreamIdType stream_id) { + void MarkStreamNotReady(StreamIdType stream_id) override { auto it = stream_infos_.find(stream_id); if (it == stream_infos_.end()) { - LOG(DFATAL) << "Stream " << stream_id << " not registered"; + SPDY_BUG << "Stream " << stream_id << " not registered"; return; } StreamInfo& stream_info = it->second; if (!stream_info.ready) { return; } - bool erased = Erase(&ready_lists_[stream_info.priority], stream_id); + bool erased = + Erase(&priority_infos_[stream_info.priority].ready_list, stream_id); DCHECK(erased); stream_info.ready = false; } // Returns true iff the number of ready streams is non-zero. - bool HasReadyStreams() const { + bool HasReadyStreams() const override { for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) { - if (!ready_lists_[i].empty()) { + if (!priority_infos_[i].ready_list.empty()) { return true; } } @@ -227,44 +252,36 @@ class PriorityWriteScheduler { } // Returns the number of ready streams. - size_t NumReadyStreams() const { + size_t NumReadyStreams() const override { size_t n = 0; for (SpdyPriority i = kV3HighestPriority; i <= kV3LowestPriority; ++i) { - n += ready_lists_[i].size(); + n += priority_infos_[i].ready_list.size(); } return n; } - // Returns the number of ready streams with the given priority. - size_t NumReadyStreams(SpdyPriority priority) const { - priority = ClampPriority(priority); - return ready_lists_[priority].size(); - } - private: + friend class test::PriorityWriteSchedulerPeer<StreamIdType>; + // 0(1) size lookup, 0(1) insert at front or back. typedef std::deque<StreamIdType> StreamIdList; // State kept for all registered streams. All ready streams have ready = true - // and should be present in ready_lists_[priority]. + // and should be present in priority_infos_[priority].ready_list. struct StreamInfo { SpdyPriority priority; bool ready; }; - typedef std::unordered_map<StreamIdType, StreamInfo> StreamInfoMap; + // State kept for each priority level. + struct PriorityInfo { + // IDs of streams that are ready to write. + StreamIdList ready_list; + // Time of latest write event for stream of this priority, in microseconds. + int64_t last_event_time_usec = 0; + }; - static SpdyPriority ClampPriority(SpdyPriority priority) { - if (priority < kV3HighestPriority) { - LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); - return kV3HighestPriority; - } - if (priority > kV3LowestPriority) { - LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); - return kV3LowestPriority; - } - return priority; - } + typedef std::unordered_map<StreamIdType, StreamInfo> StreamInfoMap; // Erases first occurrence (which should be the only one) of |stream_id| in // |ready_list|, returning true if found (and erased), or false otherwise. @@ -277,8 +294,8 @@ class PriorityWriteScheduler { return true; } - // IDs of streams that are ready to write, grouped by priority. - StreamIdList ready_lists_[kV3LowestPriority + 1]; + // Per-priority state, including ready lists. + PriorityInfo priority_infos_[kV3LowestPriority + 1]; // StreamInfos for all registered streams. StreamInfoMap stream_infos_; }; diff --git a/chromium/net/spdy/priority_write_scheduler_test.cc b/chromium/net/spdy/priority_write_scheduler_test.cc index 56f659d0d7d..dd7a01e3f8b 100644 --- a/chromium/net/spdy/priority_write_scheduler_test.cc +++ b/chromium/net/spdy/priority_write_scheduler_test.cc @@ -4,24 +4,53 @@ #include "net/spdy/priority_write_scheduler.h" +#include "net/spdy/spdy_protocol.h" +#include "net/spdy/spdy_test_utils.h" #include "net/test/gtest_util.h" namespace net { namespace test { + +template <typename StreamIdType> +class PriorityWriteSchedulerPeer { + public: + explicit PriorityWriteSchedulerPeer( + PriorityWriteScheduler<StreamIdType>* scheduler) + : scheduler_(scheduler) {} + + size_t NumReadyStreams(SpdyPriority priority) const { + return scheduler_->priority_infos_[priority].ready_list.size(); + } + + private: + PriorityWriteScheduler<StreamIdType>* scheduler_; +}; + namespace { class PriorityWriteSchedulerTest : public ::testing::Test { public: - PriorityWriteScheduler<int> scheduler_; + PriorityWriteSchedulerTest() : peer_(&scheduler_) {} + + PriorityWriteScheduler<unsigned int> scheduler_; + PriorityWriteSchedulerPeer<unsigned int> peer_; }; TEST_F(PriorityWriteSchedulerTest, RegisterUnregisterStreams) { EXPECT_FALSE(scheduler_.HasReadyStreams()); + EXPECT_FALSE(scheduler_.StreamRegistered(1)); scheduler_.RegisterStream(1, 1); + EXPECT_TRUE(scheduler_.StreamRegistered(1)); + + // Root stream counts as already registered. + EXPECT_SPDY_BUG(scheduler_.RegisterStream(kHttp2RootStreamId, 1), + "Stream 0 already registered"); // Try redundant registrations. - EXPECT_DFATAL(scheduler_.RegisterStream(1, 1), "Stream 1 already registered"); - EXPECT_DFATAL(scheduler_.RegisterStream(1, 2), "Stream 1 already registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(1, 1), + "Stream 1 already registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(1, 2), + "Stream 1 already registered"); scheduler_.RegisterStream(2, 3); @@ -32,19 +61,38 @@ TEST_F(PriorityWriteSchedulerTest, RegisterUnregisterStreams) { scheduler_.UnregisterStream(2); // Try redundant unregistration. - EXPECT_DFATAL(scheduler_.UnregisterStream(1), "Stream 1 not registered"); - EXPECT_DFATAL(scheduler_.UnregisterStream(2), "Stream 2 not registered"); + EXPECT_SPDY_BUG(scheduler_.UnregisterStream(1), "Stream 1 not registered"); + EXPECT_SPDY_BUG(scheduler_.UnregisterStream(2), "Stream 2 not registered"); +} + +TEST_F(PriorityWriteSchedulerTest, RegisterStream) { + EXPECT_FALSE(scheduler_.HasReadyStreams()); + EXPECT_FALSE(scheduler_.StreamRegistered(1)); + scheduler_.RegisterStream(1, kHttp2RootStreamId, 123, false); + EXPECT_TRUE(scheduler_.StreamRegistered(1)); + EXPECT_EQ(Http2WeightToSpdyPriority(123), scheduler_.GetStreamPriority(1)); + EXPECT_EQ(kHttp2RootStreamId, scheduler_.GetStreamParent(1)); + EXPECT_FALSE(scheduler_.HasReadyStreams()); + + EXPECT_SPDY_BUG(scheduler_.RegisterStream(1, kHttp2RootStreamId, 456, false), + "Stream 1 already registered"); + EXPECT_EQ(Http2WeightToSpdyPriority(123), scheduler_.GetStreamPriority(1)); + + EXPECT_SPDY_BUG(scheduler_.RegisterStream(2, 3, 123, false), + "Stream 3 not registered"); + EXPECT_TRUE(scheduler_.StreamRegistered(2)); } TEST_F(PriorityWriteSchedulerTest, GetStreamPriority) { - EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)), - "Stream 1 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)), + "Stream 1 not registered"); scheduler_.RegisterStream(1, 3); EXPECT_EQ(3, scheduler_.GetStreamPriority(1)); // Redundant registration shouldn't change stream priority. - EXPECT_DFATAL(scheduler_.RegisterStream(1, 4), "Stream 1 already registered"); + EXPECT_SPDY_BUG(scheduler_.RegisterStream(1, 4), + "Stream 1 already registered"); EXPECT_EQ(3, scheduler_.GetStreamPriority(1)); scheduler_.UpdateStreamPriority(1, 5); @@ -55,28 +103,28 @@ TEST_F(PriorityWriteSchedulerTest, GetStreamPriority) { EXPECT_EQ(5, scheduler_.GetStreamPriority(1)); // Test changing priority of ready stream. - EXPECT_EQ(1u, scheduler_.NumReadyStreams(5)); + EXPECT_EQ(1u, peer_.NumReadyStreams(5)); scheduler_.UpdateStreamPriority(1, 6); EXPECT_EQ(6, scheduler_.GetStreamPriority(1)); - EXPECT_EQ(0u, scheduler_.NumReadyStreams(5)); - EXPECT_EQ(1u, scheduler_.NumReadyStreams(6)); + EXPECT_EQ(0u, peer_.NumReadyStreams(5)); + EXPECT_EQ(1u, peer_.NumReadyStreams(6)); - EXPECT_EQ(1, scheduler_.PopNextReadyStream()); + EXPECT_EQ(1u, scheduler_.PopNextReadyStream()); EXPECT_EQ(6, scheduler_.GetStreamPriority(1)); scheduler_.UnregisterStream(1); - EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)), - "Stream 1 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(1)), + "Stream 1 not registered"); } TEST_F(PriorityWriteSchedulerTest, UpdateStreamPriority) { // Updating priority of unregistered stream should have no effect. - EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), - "Stream 3 not registered"); - EXPECT_DFATAL(scheduler_.UpdateStreamPriority(3, 1), - "Stream 3 not registered"); - EXPECT_DFATAL(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), - "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), + "Stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamPriority(3, 1), + "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(kV3LowestPriority, scheduler_.GetStreamPriority(3)), + "Stream 3 not registered"); scheduler_.RegisterStream(3, 1); EXPECT_EQ(1, scheduler_.GetStreamPriority(3)); @@ -93,55 +141,61 @@ TEST_F(PriorityWriteSchedulerTest, UpdateStreamPriority) { scheduler_.RegisterStream(4, 1); scheduler_.MarkStreamReady(3, false); // priority 2 scheduler_.MarkStreamReady(4, false); // priority 1 - EXPECT_EQ(4, scheduler_.PopNextReadyStream()); - EXPECT_EQ(3, scheduler_.PopNextReadyStream()); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); // Verify that lowering priority of stream 4 causes it to be returned later // by PopNextReadyStream(). scheduler_.MarkStreamReady(3, false); // priority 2 scheduler_.MarkStreamReady(4, false); // priority 1 scheduler_.UpdateStreamPriority(4, 3); - EXPECT_EQ(3, scheduler_.PopNextReadyStream()); - EXPECT_EQ(4, scheduler_.PopNextReadyStream()); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); scheduler_.UnregisterStream(3); - EXPECT_DFATAL(scheduler_.UpdateStreamPriority(3, 1), - "Stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamPriority(3, 1), + "Stream 3 not registered"); } -TEST_F(PriorityWriteSchedulerTest, HasHigherPriorityReadyStream) { - EXPECT_DFATAL(EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)), - "Stream 1 not registered"); +TEST_F(PriorityWriteSchedulerTest, GetStreamWeight) { + EXPECT_SPDY_BUG( + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(1)), + "Stream 1 not registered"); - // Add ready streams of lower and equal priority. - scheduler_.RegisterStream(1, 4); - EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)); - scheduler_.RegisterStream(2, 5); - scheduler_.MarkStreamReady(2, false); - EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)); - scheduler_.RegisterStream(3, 4); - scheduler_.MarkStreamReady(3, false); - EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)); + scheduler_.RegisterStream(1, 3); + scheduler_.RegisterStream(2, 4); + EXPECT_EQ(SpdyPriorityToHttp2Weight(3), scheduler_.GetStreamWeight(1)); + EXPECT_EQ(SpdyPriorityToHttp2Weight(4), scheduler_.GetStreamWeight(2)); - // Verify that registration of a stream with higher priority isn't - // sufficient--it needs to be marked ready. - scheduler_.RegisterStream(4, 3); - EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)); - scheduler_.MarkStreamReady(4, false); - EXPECT_TRUE(scheduler_.HasHigherPriorityReadyStream(1)); + scheduler_.UnregisterStream(1); + EXPECT_SPDY_BUG( + EXPECT_EQ(kHttp2MinStreamWeight, scheduler_.GetStreamWeight(1)), + "Stream 1 not registered"); +} - // Verify method is responsive to changes in priority. - scheduler_.UpdateStreamPriority(1, 2); - EXPECT_FALSE(scheduler_.HasHigherPriorityReadyStream(1)); +TEST_F(PriorityWriteSchedulerTest, UpdateStreamWeight) { + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 100), + "Stream 3 not registered"); + + scheduler_.RegisterStream(3, 3); + EXPECT_EQ(SpdyPriorityToHttp2Weight(3), scheduler_.GetStreamWeight(3)); + + scheduler_.UpdateStreamWeight(3, SpdyPriorityToHttp2Weight(4)); + EXPECT_EQ(SpdyPriorityToHttp2Weight(4), scheduler_.GetStreamWeight(3)); + EXPECT_EQ(4, scheduler_.GetStreamPriority(3)); + + scheduler_.UnregisterStream(3); + EXPECT_SPDY_BUG(scheduler_.UpdateStreamWeight(3, 100), + "Stream 3 not registered"); } TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) { EXPECT_FALSE(scheduler_.HasReadyStreams()); - EXPECT_DFATAL(scheduler_.MarkStreamReady(1, false), - "Stream 1 not registered"); + EXPECT_SPDY_BUG(scheduler_.MarkStreamReady(1, false), + "Stream 1 not registered"); EXPECT_FALSE(scheduler_.HasReadyStreams()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); // Add a bunch of ready streams to tail of per-priority lists. // Expected order: (P2) 4, (P3) 1, 2, 3, (P5) 5. @@ -157,21 +211,22 @@ TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBack) { scheduler_.RegisterStream(5, 5); scheduler_.MarkStreamReady(5, false); - EXPECT_EQ(4, scheduler_.PopNextReadyStream()); - EXPECT_EQ(1, scheduler_.PopNextReadyStream()); - EXPECT_EQ(2, scheduler_.PopNextReadyStream()); - EXPECT_EQ(3, scheduler_.PopNextReadyStream()); - EXPECT_EQ(5, scheduler_.PopNextReadyStream()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(1u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(5u, scheduler_.PopNextReadyStream()); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); } TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyFront) { EXPECT_FALSE(scheduler_.HasReadyStreams()); - EXPECT_DFATAL(scheduler_.MarkStreamReady(1, true), "Stream 1 not registered"); + EXPECT_SPDY_BUG(scheduler_.MarkStreamReady(1, true), + "Stream 1 not registered"); EXPECT_FALSE(scheduler_.HasReadyStreams()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); // Add a bunch of ready streams to head of per-priority lists. // Expected order: (P2) 4, (P3) 3, 2, 1, (P5) 5 @@ -187,13 +242,13 @@ TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyFront) { scheduler_.RegisterStream(5, 5); scheduler_.MarkStreamReady(5, true); - EXPECT_EQ(4, scheduler_.PopNextReadyStream()); - EXPECT_EQ(3, scheduler_.PopNextReadyStream()); - EXPECT_EQ(2, scheduler_.PopNextReadyStream()); - EXPECT_EQ(1, scheduler_.PopNextReadyStream()); - EXPECT_EQ(5, scheduler_.PopNextReadyStream()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(1u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(5u, scheduler_.PopNextReadyStream()); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); } TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBackAndFront) { @@ -214,14 +269,14 @@ TEST_F(PriorityWriteSchedulerTest, MarkStreamReadyBackAndFront) { scheduler_.MarkStreamReady(5, false); scheduler_.MarkStreamReady(6, true); - EXPECT_EQ(6, scheduler_.PopNextReadyStream()); - EXPECT_EQ(4, scheduler_.PopNextReadyStream()); - EXPECT_EQ(2, scheduler_.PopNextReadyStream()); - EXPECT_EQ(3, scheduler_.PopNextReadyStream()); - EXPECT_EQ(1, scheduler_.PopNextReadyStream()); - EXPECT_EQ(5, scheduler_.PopNextReadyStream()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_EQ(6u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(4u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(2u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(3u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(1u, scheduler_.PopNextReadyStream()); + EXPECT_EQ(5u, scheduler_.PopNextReadyStream()); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); } TEST_F(PriorityWriteSchedulerTest, MarkStreamNotReady) { @@ -234,15 +289,15 @@ TEST_F(PriorityWriteSchedulerTest, MarkStreamNotReady) { EXPECT_EQ(0u, scheduler_.NumReadyStreams()); // Empty pop should fail. - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); // Tolerate redundant marking of a stream as not ready. scheduler_.MarkStreamNotReady(1); EXPECT_EQ(0u, scheduler_.NumReadyStreams()); // Should only be able to mark registered streams. - EXPECT_DFATAL(scheduler_.MarkStreamNotReady(3), "Stream 3 not registered"); + EXPECT_SPDY_BUG(scheduler_.MarkStreamNotReady(3), "Stream 3 not registered"); } TEST_F(PriorityWriteSchedulerTest, UnregisterRemovesStream) { @@ -253,8 +308,8 @@ TEST_F(PriorityWriteSchedulerTest, UnregisterRemovesStream) { // Unregistering a stream should remove it from set of ready streams. scheduler_.UnregisterStream(3); EXPECT_EQ(0u, scheduler_.NumReadyStreams()); - EXPECT_DFATAL(EXPECT_EQ(0, scheduler_.PopNextReadyStream()), - "No ready streams available"); + EXPECT_SPDY_BUG(EXPECT_EQ(0u, scheduler_.PopNextReadyStream()), + "No ready streams available"); } TEST_F(PriorityWriteSchedulerTest, ShouldYield) { @@ -284,6 +339,26 @@ TEST_F(PriorityWriteSchedulerTest, ShouldYield) { EXPECT_TRUE(scheduler_.ShouldYield(5)); } +TEST_F(PriorityWriteSchedulerTest, GetLatestEventWithPrecedence) { + EXPECT_SPDY_BUG(scheduler_.RecordStreamEventTime(3, 5), + "Stream 3 not registered"); + EXPECT_SPDY_BUG(EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(4)), + "Stream 4 not registered"); + + for (int i = 1; i < 5; ++i) { + scheduler_.RegisterStream(i, i); + } + for (int i = 1; i < 5; ++i) { + EXPECT_EQ(0, scheduler_.GetLatestEventWithPrecedence(i)); + } + for (int i = 1; i < 5; ++i) { + scheduler_.RecordStreamEventTime(i, i * 100); + } + for (int i = 1; i < 5; ++i) { + EXPECT_EQ((i - 1) * 100, scheduler_.GetLatestEventWithPrecedence(i)); + } +} + } // namespace } // namespace test } // namespace net diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format.cc b/chromium/net/spdy/spdy_alt_svc_wire_format.cc index 2ec677754b7..38c8fdde36b 100644 --- a/chromium/net/spdy/spdy_alt_svc_wire_format.cc +++ b/chromium/net/spdy/spdy_alt_svc_wire_format.cc @@ -44,13 +44,11 @@ SpdyAltSvcWireFormat::AlternativeService::AlternativeService( const std::string& host, uint16_t port, uint32_t max_age, - double probability, VersionVector version) : protocol_id(protocol_id), host(host), port(port), max_age(max_age), - probability(probability), version(version) {} SpdyAltSvcWireFormat::AlternativeService::~AlternativeService() {} @@ -114,7 +112,6 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( ++c; // Parse parameters. uint32_t max_age = 86400; - double probability = 1.0; VersionVector version; StringPiece::const_iterator parameters_end = std::find(c, value.end(), ','); while (c != parameters_end) { @@ -150,14 +147,6 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( if (!ParsePositiveInteger32(parameter_value_begin, c, &max_age)) { return false; } - } else if (parameter_name.compare("p") == 0) { - // Probability value is enclosed in quotation marks. - if (*parameter_value_begin != '"' || *(c - 1) != '"') { - return false; - } - if (!ParseProbability(parameter_value_begin + 1, c - 1, &probability)) { - return false; - } } else if (parameter_name.compare("v") == 0) { // Version is a comma separated list of positive integers enclosed in // quotation marks. Since it can contain commas, which are not @@ -191,8 +180,7 @@ bool SpdyAltSvcWireFormat::ParseHeaderFieldValue( } } } - altsvc_vector->push_back(AlternativeService(protocol_id, host, port, - max_age, probability, version)); + altsvc_vector->emplace_back(protocol_id, host, port, max_age, version); for (; c != value.end() && (*c == ' ' || *c == '\t' || *c == ','); ++c) { } } @@ -255,9 +243,6 @@ std::string SpdyAltSvcWireFormat::SerializeHeaderFieldValue( if (altsvc.max_age != 86400) { base::StringAppendF(&value, "; ma=%d", altsvc.max_age); } - if (altsvc.probability != 1.0) { - base::StringAppendF(&value, "; p=\"%.2f\"", altsvc.probability); - } if (!altsvc.version.empty()) { value.append("; v=\""); for (VersionVector::const_iterator it = altsvc.version.begin(); @@ -355,45 +340,4 @@ bool SpdyAltSvcWireFormat::ParsePositiveInteger32( return ParsePositiveIntegerImpl<uint32_t>(c, end, value); } -// Probability is a decimal fraction between 0.0 and 1.0, inclusive, with -// optional leading zero, optional decimal point, and optional digits following -// the decimal point, with the restriction that there has to be at least one -// digit (that is, "" and "." are not valid). -// static -bool SpdyAltSvcWireFormat::ParseProbability(StringPiece::const_iterator c, - StringPiece::const_iterator end, - double* probability) { - // "" is invalid. - if (c == end) { - return false; - } - // "." is invalid. - if (end - c == 1 && *c == '.') { - return false; - } - if (*c == '1') { - *probability = 1.0; - ++c; - } else { - *probability = 0.0; - if (*c == '0') { - ++c; - } - } - if (c == end) { - return true; - } - if (*c != '.') { - return false; - } - // So far we could have had ".", "0.", or "1.". - ++c; - double place_value = 0.1; - for (; c != end && isdigit(*c); ++c) { - *probability += place_value * (*c - '0'); - place_value *= 0.1; - } - return (c == end && *probability <= 1.0); -} - } // namespace net diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format.h b/chromium/net/spdy/spdy_alt_svc_wire_format.h index de4043527a9..03eca99cc66 100644 --- a/chromium/net/spdy/spdy_alt_svc_wire_format.h +++ b/chromium/net/spdy/spdy_alt_svc_wire_format.h @@ -35,8 +35,6 @@ class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat { uint16_t port = 0; // Default is one day. uint32_t max_age = 86400; - // Default is always use. - double probability = 1.0; // Default is empty: unspecified version. VersionVector version; @@ -45,7 +43,6 @@ class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat { const std::string& host, uint16_t port, uint32_t max_age, - double probability, VersionVector version); AlternativeService(const AlternativeService& other); ~AlternativeService(); @@ -53,7 +50,7 @@ class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat { bool operator==(const AlternativeService& other) const { return protocol_id == other.protocol_id && host == other.host && port == other.port && version == other.version && - max_age == other.max_age && probability == other.probability; + max_age == other.max_age; } }; // An empty vector means alternative services should be cleared for given @@ -83,9 +80,6 @@ class NET_EXPORT_PRIVATE SpdyAltSvcWireFormat { static bool ParsePositiveInteger32(base::StringPiece::const_iterator c, base::StringPiece::const_iterator end, uint32_t* value); - static bool ParseProbability(base::StringPiece::const_iterator c, - base::StringPiece::const_iterator end, - double* probability); }; } // namespace net diff --git a/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc b/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc index 565194f4222..902ff03bec9 100644 --- a/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc +++ b/chromium/net/spdy/spdy_alt_svc_wire_format_test.cc @@ -43,11 +43,6 @@ class SpdyAltSvcWireFormatPeer { uint32_t* max_age) { return SpdyAltSvcWireFormat::ParsePositiveInteger32(c, end, max_age); } - static bool ParseProbability(StringPiece::const_iterator c, - StringPiece::const_iterator end, - double* probability) { - return SpdyAltSvcWireFormat::ParseProbability(c, end, probability); - } }; } // namespace test @@ -89,23 +84,14 @@ void FuzzHeaderFieldValue( if (i & 1 << 4) { header_field_value->append("; J=s"); } - if (i & 1 << 5) { - expected_altsvc->probability = 0.33; - header_field_value->append("; P=\".33\""); - } if (i & 1 << 6) { - expected_altsvc->probability = 0.0; expected_altsvc->version.push_back(24); - header_field_value->append("; p=\"0\";v=\"24\""); + header_field_value->append("; v=\"24\""); } if (i & 1 << 7) { expected_altsvc->max_age = 999999999; header_field_value->append("; Ma=999999999"); } - if (i & 1 << 8) { - expected_altsvc->probability = 0.1; - header_field_value->append("; P=\"0.1\""); - } if (i & 1 << 9) { header_field_value->append(";"); } @@ -140,10 +126,6 @@ void FuzzAlternativeService(int i, altsvc->max_age = 1111; expected_header_field_value->append("; ma=1111"); } - if (i & 1 << 2) { - altsvc->probability = 0.33; - expected_header_field_value->append("; p=\"0.33\""); - } if (i & 1 << 3) { altsvc->version.push_back(24); altsvc->version.push_back(25); @@ -161,7 +143,6 @@ TEST(SpdyAltSvcWireFormatTest, DefaultValues) { EXPECT_EQ("", altsvc.host); EXPECT_EQ(0u, altsvc.port); EXPECT_EQ(86400u, altsvc.max_age); - EXPECT_DOUBLE_EQ(1.0, altsvc.probability); EXPECT_TRUE(altsvc.version.empty()); } @@ -193,7 +174,6 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) { EXPECT_EQ(expected_altsvc.host, altsvc_vector[0].host); EXPECT_EQ(expected_altsvc.port, altsvc_vector[0].port); EXPECT_EQ(expected_altsvc.max_age, altsvc_vector[0].max_age); - EXPECT_DOUBLE_EQ(expected_altsvc.probability, altsvc_vector[0].probability); EXPECT_EQ(expected_altsvc.version, altsvc_vector[0].version); // Roundtrip test starting with |altsvc_vector|. @@ -208,8 +188,6 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValue) { EXPECT_EQ(expected_altsvc.host, roundtrip_altsvc_vector[0].host); EXPECT_EQ(expected_altsvc.port, roundtrip_altsvc_vector[0].port); EXPECT_EQ(expected_altsvc.max_age, roundtrip_altsvc_vector[0].max_age); - EXPECT_DOUBLE_EQ(expected_altsvc.probability, - roundtrip_altsvc_vector[0].probability); EXPECT_EQ(expected_altsvc.version, roundtrip_altsvc_vector[0].version); } } @@ -240,8 +218,6 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) { EXPECT_EQ(expected_altsvc_vector[j].host, altsvc_vector[j].host); EXPECT_EQ(expected_altsvc_vector[j].port, altsvc_vector[j].port); EXPECT_EQ(expected_altsvc_vector[j].max_age, altsvc_vector[j].max_age); - EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].probability, - altsvc_vector[j].probability); EXPECT_EQ(expected_altsvc_vector[j].version, altsvc_vector[j].version); } @@ -261,8 +237,6 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueMultiple) { roundtrip_altsvc_vector[j].port); EXPECT_EQ(expected_altsvc_vector[j].max_age, roundtrip_altsvc_vector[j].max_age); - EXPECT_DOUBLE_EQ(expected_altsvc_vector[j].probability, - roundtrip_altsvc_vector[j].probability); EXPECT_EQ(expected_altsvc_vector[j].version, roundtrip_altsvc_vector[j].version); } @@ -294,7 +268,6 @@ TEST(SpdyAltSvcWireFormatTest, RoundTrip) { EXPECT_EQ(altsvc.host, parsed_altsvc_vector[0].host); EXPECT_EQ(altsvc.port, parsed_altsvc_vector[0].port); EXPECT_EQ(altsvc.max_age, parsed_altsvc_vector[0].max_age); - EXPECT_DOUBLE_EQ(altsvc.probability, parsed_altsvc_vector[0].probability); EXPECT_EQ(altsvc.version, parsed_altsvc_vector[0].version); // Test SerializeHeaderFieldValue(). @@ -332,7 +305,6 @@ TEST(SpdyAltSvcWireFormatTest, RoundTripMultiple) { EXPECT_EQ(expected_it->host, parsed_it->host); EXPECT_EQ(expected_it->port, parsed_it->port); EXPECT_EQ(expected_it->max_age, parsed_it->max_age); - EXPECT_DOUBLE_EQ(expected_it->probability, parsed_it->probability); EXPECT_EQ(expected_it->version, parsed_it->version); } @@ -343,18 +315,33 @@ TEST(SpdyAltSvcWireFormatTest, RoundTripMultiple) { // ParseHeaderFieldValue() should return false on malformed field values: // invalid percent encoding, unmatched quotation mark, empty port, non-numeric -// characters in numeric fields, negative or larger than 1.0 probability. +// characters in numeric fields. TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) { SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; - const char* invalid_field_value_array[] = {"a%", "a%x", "a%b", "a%9z", - "a=", "a=\"", "a=\"b\"", "a=\":\"", "a=\"c:\"", "a=\"c:foo\"", - "a=\"c:42foo\"", "a=\"b:42\"bar", "a=\"b:42\" ; m", - "a=\"b:42\" ; min-age", "a=\"b:42\" ; ma", "a=\"b:42\" ; ma=", - "a=\"b:42\" ; ma=ma", "a=\"b:42\" ; ma=123bar", "a=\"b:42\" ; p=\"-2\"", - "a=\"b:42\" ; p=\"..\"", "a=\"b:42\" ; p=\"1.05\"", "a=\"b:42\" ; p=0.4", - "a=\"b:42\" ; p=\" 1.0\"", "a=\"b:42\" ; v=24", "a=\"b:42\" ; v=24,25", - "a=\"b:42\" ; v=\"-3\"", "a=\"b:42\" ; v=\"1.2\"", - "a=\"b:42\" ; v=\"24,\""}; + const char* invalid_field_value_array[] = {"a%", + "a%x", + "a%b", + "a%9z", + "a=", + "a=\"", + "a=\"b\"", + "a=\":\"", + "a=\"c:\"", + "a=\"c:foo\"", + "a=\"c:42foo\"", + "a=\"b:42\"bar", + "a=\"b:42\" ; m", + "a=\"b:42\" ; min-age", + "a=\"b:42\" ; ma", + "a=\"b:42\" ; ma=", + "a=\"b:42\" ; v=\"..\"", + "a=\"b:42\" ; ma=ma", + "a=\"b:42\" ; ma=123bar", + "a=\"b:42\" ; v=24", + "a=\"b:42\" ; v=24,25", + "a=\"b:42\" ; v=\"-3\"", + "a=\"b:42\" ; v=\"1.2\"", + "a=\"b:42\" ; v=\"24,\""}; for (const char* invalid_field_value : invalid_field_value_array) { EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue( invalid_field_value, &altsvc_vector)) @@ -367,8 +354,8 @@ TEST(SpdyAltSvcWireFormatTest, ParseHeaderFieldValueInvalid) { // of the input. TEST(SpdyAltSvcWireFormatTest, ParseTruncatedHeaderFieldValue) { SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; - const char* field_value_array[] = { - "p=\":137\"", "p=\"foo:137\"", "p%25=\"foo\\\"bar\\\\baz:137\""}; + const char* field_value_array[] = {"a=\":137\"", "a=\"foo:137\"", + "a%25=\"foo\\\"bar\\\\baz:137\""}; for (const std::string& field_value : field_value_array) { for (size_t len = 1; len < field_value.size(); ++len) { EXPECT_FALSE(SpdyAltSvcWireFormat::ParseHeaderFieldValue( @@ -447,8 +434,9 @@ TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityValid) { // Test ParseAltAuthority() on invalid input: empty string, no port, zero port, // non-digit characters following port. TEST(SpdyAltSvcWireFormatTest, ParseAltAuthorityInvalid) { - const char* invalid_input_array[] = {"", ":", "foo:", ":bar", ":0", "foo:0", - ":12bar", "foo:23bar", " ", ":12 ", "foo:12 "}; + const char* invalid_input_array[] = {"", ":", "foo:", ":bar", + ":0", "foo:0", ":12bar", "foo:23bar", + " ", ":12 ", "foo:12 "}; for (const char* invalid_input : invalid_input_array) { StringPiece input(invalid_input); std::string host; @@ -526,71 +514,6 @@ TEST(SpdyAltSvcWireFormatTest, ParseIntegerOverflow) { input.begin(), input.end(), &value32)); } -// Test ParseProbability() on valid input. -TEST(SpdyAltSvcWireFormatTest, ParseProbabilityValid) { - StringPiece input("0"); - double probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(0.0, probability); - - input = StringPiece("0."); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(0.0, probability); - - input = StringPiece("0.0"); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(0.0, probability); - - input = StringPiece("1"); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(1.0, probability); - - input = StringPiece("1."); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(1.0, probability); - - input = StringPiece("1.0"); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(1.0, probability); - - input = StringPiece("0.37"); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(0.37, probability); - - input = StringPiece("0.72"); - probability = -2.0; - ASSERT_TRUE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - EXPECT_DOUBLE_EQ(0.72, probability); -} - -// Test ParseProbability() on invalid input: empty string, non-digit characters, -// negative input, larger than 1.0. -TEST(SpdyAltSvcWireFormatTest, ParseProbabilityInvalid) { - const char* invalid_input_array[] = {"", " ", ".", "a", "-2", "-0", "0a", - "1b ", "0.9z2", "0.33 ", "0.98x", "2.0", "1.0001", "1.00001", - "1.000001"}; - for (const char* invalid_input : invalid_input_array) { - StringPiece input(invalid_input); - double probability; - EXPECT_FALSE(test::SpdyAltSvcWireFormatPeer::ParseProbability( - input.begin(), input.end(), &probability)); - } -} - } // namespace } // namespace net diff --git a/chromium/net/spdy/spdy_buffer.cc b/chromium/net/spdy/spdy_buffer.cc index be783fc6a1a..28e807def4d 100644 --- a/chromium/net/spdy/spdy_buffer.cc +++ b/chromium/net/spdy/spdy_buffer.cc @@ -22,14 +22,14 @@ const size_t kMaxSpdyFrameSize = 0x00ffffff; // Makes a SpdySerializedFrame with |size| bytes of data copied from |data|. // |data| must be non-NULL and |size| must be positive. -scoped_ptr<SpdySerializedFrame> MakeSpdySerializedFrame(const char* data, - size_t size) { +std::unique_ptr<SpdySerializedFrame> MakeSpdySerializedFrame(const char* data, + size_t size) { DCHECK(data); CHECK_GT(size, 0u); CHECK_LE(size, kMaxSpdyFrameSize); - scoped_ptr<char[]> frame_data(new char[size]); + std::unique_ptr<char[]> frame_data(new char[size]); std::memcpy(frame_data.get(), data, size); - scoped_ptr<SpdySerializedFrame> frame(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> frame(new SpdySerializedFrame( frame_data.release(), size, true /* owns_buffer */)); return frame; } @@ -57,7 +57,7 @@ class SpdyBuffer::SharedFrameIOBuffer : public IOBuffer { DISALLOW_COPY_AND_ASSIGN(SharedFrameIOBuffer); }; -SpdyBuffer::SpdyBuffer(scoped_ptr<SpdySerializedFrame> frame) +SpdyBuffer::SpdyBuffer(std::unique_ptr<SpdySerializedFrame> frame) : shared_frame_(new SharedFrame()), offset_(0) { shared_frame_->data = std::move(frame); } diff --git a/chromium/net/spdy/spdy_buffer.h b/chromium/net/spdy/spdy_buffer.h index d12c89fcf83..0d9ffbf248b 100644 --- a/chromium/net/spdy/spdy_buffer.h +++ b/chromium/net/spdy/spdy_buffer.h @@ -6,12 +6,12 @@ #define NET_SPDY_SPDY_BUFFER_H_ #include <cstddef> +#include <memory> #include <vector> #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" namespace net { @@ -47,7 +47,7 @@ class NET_EXPORT_PRIVATE SpdyBuffer { // Construct with the data in the given frame. Assumes that data is // owned by |frame| or outlives it. - explicit SpdyBuffer(scoped_ptr<SpdySerializedFrame> frame); + explicit SpdyBuffer(std::unique_ptr<SpdySerializedFrame> frame); // Construct with a copy of the given raw data. |data| must be // non-NULL and |size| must be non-zero. @@ -88,7 +88,8 @@ class NET_EXPORT_PRIVATE SpdyBuffer { // Ref-count the passed-in SpdySerializedFrame to support the semantics of // |GetIOBufferForRemainingData()|. - typedef base::RefCountedData<scoped_ptr<SpdySerializedFrame>> SharedFrame; + typedef base::RefCountedData<std::unique_ptr<SpdySerializedFrame>> + SharedFrame; class SharedFrameIOBuffer; diff --git a/chromium/net/spdy/spdy_buffer_producer.cc b/chromium/net/spdy/spdy_buffer_producer.cc index 8f18d19f24f..46d766bb675 100644 --- a/chromium/net/spdy/spdy_buffer_producer.cc +++ b/chromium/net/spdy/spdy_buffer_producer.cc @@ -16,12 +16,12 @@ SpdyBufferProducer::SpdyBufferProducer() {} SpdyBufferProducer::~SpdyBufferProducer() {} -SimpleBufferProducer::SimpleBufferProducer(scoped_ptr<SpdyBuffer> buffer) +SimpleBufferProducer::SimpleBufferProducer(std::unique_ptr<SpdyBuffer> buffer) : buffer_(std::move(buffer)) {} SimpleBufferProducer::~SimpleBufferProducer() {} -scoped_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() { +std::unique_ptr<SpdyBuffer> SimpleBufferProducer::ProduceBuffer() { DCHECK(buffer_); return std::move(buffer_); } diff --git a/chromium/net/spdy/spdy_buffer_producer.h b/chromium/net/spdy/spdy_buffer_producer.h index 849ecd24dfe..8d09f7b4ea2 100644 --- a/chromium/net/spdy/spdy_buffer_producer.h +++ b/chromium/net/spdy/spdy_buffer_producer.h @@ -5,9 +5,10 @@ #ifndef NET_SPDY_SPDY_BUFFER_PRODUCER_H_ #define NET_SPDY_SPDY_BUFFER_PRODUCER_H_ +#include <memory> + #include "base/compiler_specific.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" namespace net { @@ -22,7 +23,7 @@ class NET_EXPORT_PRIVATE SpdyBufferProducer { SpdyBufferProducer(); // Produces the buffer to be written. Will be called at most once. - virtual scoped_ptr<SpdyBuffer> ProduceBuffer() = 0; + virtual std::unique_ptr<SpdyBuffer> ProduceBuffer() = 0; virtual ~SpdyBufferProducer(); @@ -33,14 +34,14 @@ class NET_EXPORT_PRIVATE SpdyBufferProducer { // A simple wrapper around a single SpdyBuffer. class NET_EXPORT_PRIVATE SimpleBufferProducer : public SpdyBufferProducer { public: - explicit SimpleBufferProducer(scoped_ptr<SpdyBuffer> buffer); + explicit SimpleBufferProducer(std::unique_ptr<SpdyBuffer> buffer); ~SimpleBufferProducer() override; - scoped_ptr<SpdyBuffer> ProduceBuffer() override; + std::unique_ptr<SpdyBuffer> ProduceBuffer() override; private: - scoped_ptr<SpdyBuffer> buffer_; + std::unique_ptr<SpdyBuffer> buffer_; DISALLOW_COPY_AND_ASSIGN(SimpleBufferProducer); }; diff --git a/chromium/net/spdy/spdy_buffer_unittest.cc b/chromium/net/spdy/spdy_buffer_unittest.cc index 46a5c2b63fd..3dd49420b23 100644 --- a/chromium/net/spdy/spdy_buffer_unittest.cc +++ b/chromium/net/spdy/spdy_buffer_unittest.cc @@ -6,11 +6,11 @@ #include <cstddef> #include <cstring> +#include <memory> #include <string> #include "base/bind.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "net/base/io_buffer.h" #include "net/spdy/spdy_protocol.h" #include "testing/gtest/include/gtest/gtest.h" @@ -32,8 +32,9 @@ std::string BufferToString(const SpdyBuffer& buffer) { // Construct a SpdyBuffer from a SpdySerializedFrame and make sure its data // points to the frame's underlying data. TEST_F(SpdyBufferTest, FrameConstructor) { - SpdyBuffer buffer(scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame( - const_cast<char*>(kData), kDataSize, false /* owns_buffer */))); + SpdyBuffer buffer( + std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( + const_cast<char*>(kData), kDataSize, false /* owns_buffer */))); EXPECT_EQ(kData, buffer.GetRemainingData()); EXPECT_EQ(kDataSize, buffer.GetRemainingSize()); @@ -119,7 +120,7 @@ TEST_F(SpdyBufferTest, GetIOBufferForRemainingData) { // Make sure the IOBuffer returned by GetIOBufferForRemainingData() // outlives the buffer itself. TEST_F(SpdyBufferTest, IOBufferForRemainingDataOutlivesBuffer) { - scoped_ptr<SpdyBuffer> buffer(new SpdyBuffer(kData, kDataSize)); + std::unique_ptr<SpdyBuffer> buffer(new SpdyBuffer(kData, kDataSize)); scoped_refptr<IOBuffer> io_buffer = buffer->GetIOBufferForRemainingData(); buffer.reset(); diff --git a/chromium/net/spdy/spdy_bug_tracker.h b/chromium/net/spdy/spdy_bug_tracker.h new file mode 100644 index 00000000000..fc05f68d7e2 --- /dev/null +++ b/chromium/net/spdy/spdy_bug_tracker.h @@ -0,0 +1,14 @@ +// Copyright (c) 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. + +#ifndef NET_SPDY_SPDY_BUG_TRACKER_H_ +#define NET_SPDY_SPDY_BUG_TRACKER_H_ + +#include "base/logging.h" + +#define SPDY_BUG LOG(DFATAL) +#define SPDY_BUG_IF(condition) LOG_IF(DFATAL, (condition)) +#define FLAGS_spdy_always_log_bugs_for_tests (true) + +#endif // NET_SPDY_SPDY_BUG_TRACKER_H_ diff --git a/chromium/net/spdy/spdy_frame_builder.cc b/chromium/net/spdy/spdy_frame_builder.cc index 7911b808ac7..91a48b12a95 100644 --- a/chromium/net/spdy/spdy_frame_builder.cc +++ b/chromium/net/spdy/spdy_frame_builder.cc @@ -7,6 +7,7 @@ #include <limits> #include "base/logging.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_framer.h" #include "net/spdy/spdy_protocol.h" @@ -108,7 +109,7 @@ bool SpdyFrameBuilder::BeginNewFrame(const SpdyFramer& framer, if (length_ > 0) { // Update length field for previous frame. OverwriteLength(framer, length_ - framer.GetPrefixLength(type)); - DLOG_IF(DFATAL, SpdyConstants::GetFrameMaximumSize(version_) < length_) + SPDY_BUG_IF(SpdyConstants::GetFrameMaximumSize(version_) < length_) << "Frame length " << length_ << " is longer than the maximum allowed length."; } diff --git a/chromium/net/spdy/spdy_frame_builder.h b/chromium/net/spdy/spdy_frame_builder.h index d1f9535f2f6..86c8ee001e6 100644 --- a/chromium/net/spdy/spdy_frame_builder.h +++ b/chromium/net/spdy/spdy_frame_builder.h @@ -8,12 +8,13 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "base/sys_byteorder.h" #include "net/base/net_export.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_protocol.h" namespace net { @@ -76,7 +77,7 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder { // Takes the buffer from the SpdyFrameBuilder. SpdySerializedFrame take() { if (version_ == HTTP2) { - DLOG_IF(DFATAL, SpdyConstants::GetFrameMaximumSize(version_) < length_) + SPDY_BUG_IF(SpdyConstants::GetFrameMaximumSize(version_) < length_) << "Frame length " << length_ << " is longer than the maximum allowed length."; } @@ -138,7 +139,7 @@ class NET_EXPORT_PRIVATE SpdyFrameBuilder { // write of given size, in bytes. bool CanWrite(size_t length) const; - scoped_ptr<char[]> buffer_; + std::unique_ptr<char[]> buffer_; size_t capacity_; // Allocation size of payload, set by constructor. size_t length_; // Length of the latest frame in the buffer. size_t offset_; // Position at which the latest frame begins. diff --git a/chromium/net/spdy/spdy_frame_reader_test.cc b/chromium/net/spdy/spdy_frame_reader_test.cc index ca178de33f5..c68f3f42cf4 100644 --- a/chromium/net/spdy/spdy_frame_reader_test.cc +++ b/chromium/net/spdy/spdy_frame_reader_test.cc @@ -2,12 +2,13 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "net/spdy/spdy_frame_reader.h" + #include <algorithm> #include <iostream> +#include <memory> -#include "base/memory/scoped_ptr.h" #include "base/sys_byteorder.h" -#include "net/spdy/spdy_frame_reader.h" #include "testing/platform_test.h" namespace net { diff --git a/chromium/net/spdy/spdy_framer.cc b/chromium/net/spdy/spdy_framer.cc index ab242b8e1c9..7ead331721b 100644 --- a/chromium/net/spdy/spdy_framer.cc +++ b/chromium/net/spdy/spdy_framer.cc @@ -7,21 +7,24 @@ #include <string.h> #include <algorithm> +#include <ios> #include <iterator> +#include <memory> #include <string> #include <vector> #include "base/lazy_instance.h" -#include "base/memory/scoped_ptr.h" #include "base/metrics/histogram_macros.h" #include "net/quic/quic_flags.h" #include "net/spdy/hpack/hpack_constants.h" +#include "net/spdy/spdy_bitmasks.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_frame_builder.h" #include "net/spdy/spdy_frame_reader.h" -#include "net/spdy/spdy_bitmasks.h" #include "third_party/zlib/zlib.h" using base::StringPiece; +using std::hex; using std::string; using std::vector; @@ -144,7 +147,7 @@ SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(SpdyMajorVersion version, SettingsFlagsAndId::SettingsFlagsAndId(uint8_t flags, uint32_t id) : flags_(flags), id_(id & 0x00ffffff) { - LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id; + SPDY_BUG_IF(id > (1u << 24)) << "SPDY setting ID too large: " << id; } uint32_t SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version) const { @@ -172,12 +175,13 @@ SpdyFramer::SpdyFramer(SpdyMajorVersion version) enable_compression_(true), syn_frame_processed_(false), probable_http_response_(false), - end_stream_when_done_(false), - spdy_on_stream_end_(FLAGS_spdy_on_stream_end) { + end_stream_when_done_(false) { DCHECK(protocol_version_ == SPDY3 || protocol_version_ == HTTP2); - DCHECK_LE(kMaxControlFrameSize, - SpdyConstants::GetFrameMaximumSize(protocol_version_) + - SpdyConstants::GetControlFrameHeaderSize(protocol_version_)); + // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it + // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. + // Therefore this assertion is unnecessarily strict. + static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, + "Our send limit should be at most our receive limit"); Reset(); } @@ -243,6 +247,7 @@ size_t SpdyFramer::GetSynReplyMinimumSize() const { return size; } +// TODO(jamessynge): Rename this to GetRstStreamSize as the frame is fixed size. size_t SpdyFramer::GetRstStreamMinimumSize() const { // Size, in bytes, of a RST_STREAM frame. if (protocol_version_ == SPDY3) { @@ -419,6 +424,8 @@ const char* SpdyFramer::ErrorCodeToString(int error_code) { switch (error_code) { case SPDY_NO_ERROR: return "NO_ERROR"; + case SPDY_INVALID_STREAM_ID: + return "INVALID_STREAM_ID"; case SPDY_INVALID_CONTROL_FRAME: return "INVALID_CONTROL_FRAME"; case SPDY_CONTROL_PAYLOAD_TOO_LARGE: @@ -433,6 +440,8 @@ const char* SpdyFramer::ErrorCodeToString(int error_code) { return "DECOMPRESS_FAILURE"; case SPDY_COMPRESS_FAILURE: return "COMPRESS_FAILURE"; + case SPDY_INVALID_PADDING: + return "SPDY_INVALID_PADDING"; case SPDY_INVALID_DATA_FRAME_FLAGS: return "SPDY_INVALID_DATA_FRAME_FLAGS"; case SPDY_INVALID_CONTROL_FRAME_FLAGS: @@ -638,8 +647,8 @@ size_t SpdyFramer::ProcessInput(const char* data, size_t len) { } default: - LOG(DFATAL) << "Invalid value for " << display_protocol_ - << " framer state: " << state_; + SPDY_BUG << "Invalid value for " << display_protocol_ + << " framer state: " << state_; // This ensures that we don't infinite-loop if state_ gets an // invalid value somehow, such as due to a SpdyFramer getting deleted // from a callback it calls. @@ -679,6 +688,75 @@ void SpdyFramer::SpdySettingsScratch::Reset() { last_setting_id = -1; } +SpdyFrameType SpdyFramer::ValidateFrameHeader(bool is_control_frame, + int frame_type_field) { + if (!SpdyConstants::IsValidFrameType(protocol_version_, frame_type_field)) { + if (protocol_version_ == SPDY3) { + if (is_control_frame) { + DLOG(WARNING) << "Invalid control frame type " << frame_type_field + << " (protocol version: " << protocol_version_ << ")"; + set_error(SPDY_INVALID_CONTROL_FRAME); + } else { + // Else it's a SPDY3 data frame which we don't validate further here + } + } else { + // In HTTP2 we ignore unknown frame types for extensibility, as long as + // the rest of the control frame header is valid. + // We rely on the visitor to check validity of current_frame_stream_id_. + bool valid_stream = + visitor_->OnUnknownFrame(current_frame_stream_id_, frame_type_field); + if (expect_continuation_) { + // Report an unexpected frame error and close the connection + // if we expect a continuation and receive an unknown frame. + DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " + << "frame, but instead received an unknown frame of type " + << frame_type_field; + set_error(SPDY_UNEXPECTED_FRAME); + } else if (!valid_stream) { + // Report an invalid frame error and close the stream if the + // stream_id is not valid. + DLOG(WARNING) << "Unknown control frame type " << frame_type_field + << " received on invalid stream " + << current_frame_stream_id_; + set_error(SPDY_INVALID_CONTROL_FRAME); + } else { + DVLOG(1) << "Ignoring unknown frame type."; + CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); + } + } + return DATA; + } + + SpdyFrameType frame_type = + SpdyConstants::ParseFrameType(protocol_version_, frame_type_field); + + if (protocol_version_ == HTTP2) { + if (!SpdyConstants::IsValidHTTP2FrameStreamId(current_frame_stream_id_, + frame_type)) { + DLOG(ERROR) << "The framer received an invalid streamID of " + << current_frame_stream_id_ << " for a frame of type " + << FrameTypeToString(frame_type); + set_error(SPDY_INVALID_STREAM_ID); + return frame_type; + } + + // Ensure that we see a CONTINUATION frame iff we expect to. + if ((frame_type == CONTINUATION) != (expect_continuation_ != 0)) { + if (expect_continuation_ != 0) { + DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " + << "frame, but instead received a frame of type " + << FrameTypeToString(frame_type); + } else { + DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; + } + set_error(SPDY_UNEXPECTED_FRAME); + return frame_type; + } + } + + return frame_type; +} + size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { // This should only be called when we're in the SPDY_READING_COMMON_HEADER // state. @@ -721,8 +799,6 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { set_error(SPDY_UNSUPPORTED_VERSION); return 0; } - // We check control_frame_type_field's validity in - // ProcessControlFrameHeader(). uint16_t control_frame_type_field_uint16; successful_read = reader.ReadUInt16(&control_frame_type_field_uint16); control_frame_type_field = control_frame_type_field_uint16; @@ -768,24 +844,8 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { DCHECK(successful_read); remaining_data_length_ = current_frame_length_ - reader.GetBytesConsumed(); - - // Before we accept a DATA frame, we need to make sure we're not in the - // middle of processing a header block. - const bool is_continuation_frame = - (control_frame_type_field == - SpdyConstants::SerializeFrameType(protocol_version_, CONTINUATION)); - if ((expect_continuation_ != 0) != is_continuation_frame) { - if (expect_continuation_ != 0) { - DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " - << "frame, but instead received frame type " - << control_frame_type_field; - } else { - DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; - } - set_error(SPDY_UNEXPECTED_FRAME); - return original_len - len; - } } + DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() : GetDataFrameMinimumSize(), reader.GetBytesConsumed()); @@ -807,6 +867,13 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { } } + current_frame_type_ = + ValidateFrameHeader(is_control_frame, control_frame_type_field); + + if (state_ == SPDY_ERROR || state_ == SPDY_IGNORE_REMAINING_PAYLOAD) { + return original_len - len; + } + // if we're here, then we have the common header all received. if (!is_control_frame) { if (protocol_version_ == HTTP2) { @@ -819,8 +886,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { if (protocol_version_ == SPDY3) { valid_data_flags = DATA_FLAG_FIN; } else { - valid_data_flags = - DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED; + valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED; } if (current_frame_flags_ & ~valid_data_flags) { @@ -834,12 +900,7 @@ size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) { } else { // Empty data frame. if (current_frame_flags_ & DATA_FLAG_FIN) { - if (spdy_on_stream_end_) { - visitor_->OnStreamEnd(current_frame_stream_id_); - } else { - visitor_->OnStreamFrameData(current_frame_stream_id_, nullptr, 0, - true); - } + visitor_->OnStreamEnd(current_frame_stream_id_); } CHANGE_STATE(SPDY_FRAME_COMPLETE); } @@ -855,38 +916,6 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { DCHECK_EQ(SPDY_NO_ERROR, error_code_); DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_.len()); - if (!SpdyConstants::IsValidFrameType(protocol_version_, - control_frame_type_field)) { - if (protocol_version_ == SPDY3) { - DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field - << " (protocol version: " << protocol_version_ << ")"; - set_error(SPDY_INVALID_CONTROL_FRAME); - return; - } else { - // In HTTP2 we ignore unknown frame types for extensibility, as long as - // the rest of the control frame header is valid. - // We rely on the visitor to check validity of current_frame_stream_id_. - bool valid_stream = visitor_->OnUnknownFrame(current_frame_stream_id_, - control_frame_type_field); - if (valid_stream) { - DVLOG(1) << "Ignoring unknown frame type."; - CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); - } else { - // Report an invalid frame error and close the stream if the - // stream_id is not valid. - DLOG(WARNING) << "Unknown control frame type " - << control_frame_type_field - << " received on invalid stream " - << current_frame_stream_id_; - set_error(SPDY_INVALID_CONTROL_FRAME); - } - return; - } - } - - current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version_, - control_frame_type_field); - // Do some sanity checking on the control frame sizes and flags. switch (current_frame_type_) { case SYN_STREAM: @@ -905,13 +934,12 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { } break; case RST_STREAM: - if ((current_frame_length_ != GetRstStreamMinimumSize() && - protocol_version_ == SPDY3) || - (current_frame_length_ < GetRstStreamMinimumSize() && - protocol_version_ == HTTP2)) { + if (current_frame_length_ != GetRstStreamMinimumSize()) { set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for RST_STREAM frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; case SETTINGS: @@ -932,21 +960,31 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); } else if (protocol_version_ == HTTP2 && - current_frame_flags_ & ~SETTINGS_FLAG_ACK) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); - } else if (protocol_version_ == HTTP2 && current_frame_flags_ & SETTINGS_FLAG_ACK && current_frame_length_ > GetSettingsMinimumSize()) { set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); + } else if (protocol_version_ == HTTP2 && + current_frame_flags_ & ~SETTINGS_FLAG_ACK) { + VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= SETTINGS_FLAG_ACK; } break; } case PING: if (current_frame_length_ != GetPingSize()) { set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); - } else if ((protocol_version_ == SPDY3 && current_frame_flags_ != 0) || - (current_frame_flags_ & ~PING_FLAG_ACK)) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + } else { + if (protocol_version_ == SPDY3 && current_frame_flags_ != 0) { + VLOG(1) << "Undefined frame flags for PING frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; + } else if (protocol_version_ == HTTP2 && + current_frame_flags_ & ~PING_FLAG_ACK) { + VLOG(1) << "Undefined frame flags for PING frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= PING_FLAG_ACK; + } } break; case GOAWAY: @@ -960,7 +998,9 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { current_frame_length_ < GetGoAwayMinimumSize())) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for GOAWAY frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; } @@ -977,13 +1017,18 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (protocol_version_ == SPDY3 && current_frame_flags_ & ~CONTROL_FLAG_FIN) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= CONTROL_FLAG_FIN; } else if (protocol_version_ == HTTP2 && current_frame_flags_ & ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | - HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | - HEADERS_FLAG_PADDED)) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED)) { + VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= + (CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | + HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED); } } break; @@ -991,7 +1036,9 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { if (current_frame_length_ != GetWindowUpdateSize()) { set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for WINDOW_UPDATE frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; case BLOCKED: @@ -999,19 +1046,26 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { current_frame_length_ != GetBlockedSize()) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for BLOCKED frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; case PUSH_PROMISE: if (current_frame_length_ < GetPushPromiseMinimumSize()) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (protocol_version_ == SPDY3 && current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } else if (protocol_version_ == HTTP2 && current_frame_flags_ & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= + (PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED); } break; case CONTINUATION: @@ -1019,14 +1073,18 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { current_frame_length_ < GetContinuationMinimumSize()) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for CONTINUATION frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ &= HEADERS_FLAG_END_HEADERS; } break; case ALTSVC: if (current_frame_length_ <= GetAltSvcMinimumSize()) { set_error(SPDY_INVALID_CONTROL_FRAME); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for ALTSVC frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; case PRIORITY: @@ -1034,7 +1092,9 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { current_frame_length_ != GetPrioritySize()) { set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); } else if (current_frame_flags_ != 0) { - set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); + VLOG(1) << "Undefined frame flags for PRIORITY frame: " << hex + << static_cast<int>(current_frame_flags_); + current_frame_flags_ = 0; } break; default: @@ -1055,7 +1115,7 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { } if (current_frame_length_ > - SpdyConstants::GetFrameMaximumSize(protocol_version_) + + kSpdyInitialFrameSizeLimit + SpdyConstants::GetControlFrameHeaderSize(protocol_version_)) { DLOG(WARNING) << "Received control frame of type " << current_frame_type_ << " with way too big of a payload: " @@ -1125,8 +1185,8 @@ void SpdyFramer::ProcessControlFrameHeader(int control_frame_type_field) { // We should already be in an error state. Double-check. DCHECK_EQ(SPDY_ERROR, state_); if (state_ != SPDY_ERROR) { - LOG(DFATAL) << display_protocol_ - << " control frame buffer too small for fixed-length frame."; + SPDY_BUG << display_protocol_ + << " control frame buffer too small for fixed-length frame."; set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); } return; @@ -1524,7 +1584,7 @@ size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data, // expect_continuation_ != 0, so this doubles as a check // that current_frame_stream_id != 0. if (current_frame_stream_id_ != expect_continuation_) { - set_error(SPDY_INVALID_CONTROL_FRAME); + set_error(SPDY_UNEXPECTED_FRAME); return original_len - len; } if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) { @@ -1569,8 +1629,14 @@ size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data, current_frame_type_ != HEADERS && current_frame_type_ != PUSH_PROMISE && current_frame_type_ != CONTINUATION) { - LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock."; + SPDY_BUG << "Unhandled frame type in ProcessControlFrameHeaderBlock."; + } + + if (remaining_padding_payload_length_ > remaining_data_length_) { + set_error(SPDY_INVALID_PADDING); + return data_len; } + size_t process_bytes = std::min( data_len, remaining_data_length_ - remaining_padding_payload_length_); if (is_hpack_header_block) { @@ -1989,6 +2055,7 @@ size_t SpdyFramer::ProcessRstStreamFramePayload(const char* data, size_t len) { } // Handle remaining data as opaque. + // TODO(jamessynge): Remove support for variable length/opaque trailer. bool processed_successfully = true; if (len > 0) { processed_successfully = visitor_->OnRstStreamFrameData(data, len); @@ -2074,7 +2141,7 @@ size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) { } if (remaining_padding_payload_length_ > remaining_data_length_) { - set_error(SPDY_INVALID_DATA_FRAME_FLAGS); + set_error(SPDY_INVALID_PADDING); return 0; } CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); @@ -2089,7 +2156,8 @@ size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); if (current_frame_type_ == DATA && amount_to_discard > 0) { - DCHECK_EQ(HTTP2, protocol_version_); + SPDY_BUG_IF(protocol_version_ == SPDY3) + << "Padding invalid for SPDY version " << protocol_version_; visitor_->OnStreamPadding(current_frame_stream_id_, amount_to_discard); } data += amount_to_discard; @@ -2105,11 +2173,7 @@ size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { ((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 || end_stream_when_done_)) { end_stream_when_done_ = false; - if (spdy_on_stream_end_) { - visitor_->OnStreamEnd(current_frame_stream_id_); - } else { - visitor_->OnStreamFrameData(current_frame_stream_id_, nullptr, 0, true); - } + visitor_->OnStreamEnd(current_frame_stream_id_); } CHANGE_STATE(SPDY_FRAME_COMPLETE); } @@ -2124,8 +2188,8 @@ size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { // Only inform the visitor if there is data. if (amount_to_forward) { - visitor_->OnStreamFrameData( - current_frame_stream_id_, data, amount_to_forward, false); + visitor_->OnStreamFrameData(current_frame_stream_id_, data, + amount_to_forward); } } data += amount_to_forward; @@ -2197,9 +2261,9 @@ bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, (*block)[name] = value; } if (reader.GetBytesConsumed() != header_length) { - LOG(DFATAL) << "Buffer expected to consist entirely of headers, but only " - << reader.GetBytesConsumed() << " bytes consumed, from " - << header_length; + SPDY_BUG << "Buffer expected to consist entirely of headers, but only " + << reader.GetBytesConsumed() << " bytes consumed, from " + << header_length; return false; } @@ -2290,7 +2354,7 @@ SpdySerializedFrame SpdyFramer::SerializeSynStream( // Sanitize priority. uint8_t priority = syn_stream.priority(); if (priority > GetLowestPriority()) { - DLOG(DFATAL) << "Priority out-of-bounds."; + SPDY_BUG << "Priority out-of-bounds."; priority = GetLowestPriority(); } @@ -2514,7 +2578,7 @@ SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { SpdyPriority priority = static_cast<SpdyPriority>(headers.priority()); if (headers.has_priority()) { if (headers.priority() > GetLowestPriority()) { - DLOG(DFATAL) << "Priority out-of-bounds."; + SPDY_BUG << "Priority out-of-bounds."; priority = GetLowestPriority(); } size += 5; @@ -2981,7 +3045,7 @@ bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( // Get a decompressor or set error. z_stream* decomp = GetHeaderDecompressor(); if (decomp == NULL) { - LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers."; + SPDY_BUG << "Couldn't get decompressor for handling compressed headers."; set_error(SPDY_DECOMPRESS_FAILURE); return false; } @@ -3101,7 +3165,7 @@ void SpdyFramer::SerializeHeaderBlock(SpdyFrameBuilder* builder, z_stream* compressor = GetHeaderCompressor(); if (!compressor) { - LOG(DFATAL) << "Could not obtain compressor."; + SPDY_BUG << "Could not obtain compressor."; return; } // Create an output frame. diff --git a/chromium/net/spdy/spdy_framer.h b/chromium/net/spdy/spdy_framer.h index 7375333d6f5..d67d41c937f 100644 --- a/chromium/net/spdy/spdy_framer.h +++ b/chromium/net/spdy/spdy_framer.h @@ -13,7 +13,6 @@ #include <string> #include <utility> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "base/sys_byteorder.h" #include "net/base/net_export.h" @@ -112,12 +111,9 @@ class NET_EXPORT_PRIVATE SpdyFramerVisitorInterface { // |stream_id| The stream receiving data. // |data| A buffer containing the data received. // |len| The length of the data buffer. - // When the other side has finished sending data on this stream, - // this method will be called with a zero-length buffer. virtual void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) = 0; + size_t len) = 0; // Called when the other side has finished sending data on this stream. // |stream_id| The stream that was receivin data. @@ -329,6 +325,7 @@ class NET_EXPORT_PRIVATE SpdyFramer { // SPDY error codes. enum SpdyError { SPDY_NO_ERROR, + SPDY_INVALID_STREAM_ID, // Stream ID is invalid SPDY_INVALID_CONTROL_FRAME, // Control frame is mal-formatted. SPDY_CONTROL_PAYLOAD_TOO_LARGE, // Control frame payload was too large. SPDY_ZLIB_INIT_FAILURE, // The Zlib library could not initialize. @@ -337,6 +334,7 @@ class NET_EXPORT_PRIVATE SpdyFramer { SPDY_COMPRESS_FAILURE, // There was an error compressing. SPDY_GOAWAY_FRAME_CORRUPT, // GOAWAY frame could not be parsed. SPDY_RST_STREAM_FRAME_CORRUPT, // RST_STREAM frame could not be parsed. + SPDY_INVALID_PADDING, // HEADERS or DATA frame padding invalid SPDY_INVALID_DATA_FRAME_FLAGS, // Data frame has invalid flags. SPDY_INVALID_CONTROL_FRAME_FLAGS, // Control frame has invalid flags. SPDY_UNEXPECTED_FRAME, // Frame received out of order. @@ -544,12 +542,14 @@ class NET_EXPORT_PRIVATE SpdyFramer { bool probable_http_response() const { return probable_http_response_; } - SpdyPriority GetLowestPriority() const { return 7; } + SpdyPriority GetLowestPriority() const { return kV3LowestPriority; } - SpdyPriority GetHighestPriority() const { return 0; } + SpdyPriority GetHighestPriority() const { return kV3HighestPriority; } - // Interpolates SpdyPriority values into SPDY4/HTTP2 priority weights, - // and vice versa. + // Interpolates SpdyPriority values into SPDY4/HTTP2 priority weights, and + // vice versa. Note that these methods accept/return weight values in their + // on-the-wire form, i.e. in range [0, 255], rather than their effective + // values in range [1, 256]. static uint8_t MapPriorityToWeight(SpdyPriority priority); static SpdyPriority MapWeightToPriority(uint8_t weight); @@ -592,7 +592,7 @@ class NET_EXPORT_PRIVATE SpdyFramer { size_t len() const { return len_; } private: - scoped_ptr<char[]> buffer_; + std::unique_ptr<char[]> buffer_; size_t capacity_; size_t len_; }; @@ -632,6 +632,18 @@ class NET_EXPORT_PRIVATE SpdyFramer { size_t ProcessAltSvcFramePayload(const char* data, size_t len); size_t ProcessIgnoredControlFramePayload(/*const char* data,*/ size_t len); + // Validates the frame header against the current protocol, e.g. + // Frame type must be known, must specify a non-zero stream id. + // + // is_control_frame: the control bit for SPDY3 + // frame_type_field: the unparsed frame type octet(s) + // + // For valid frames, returns the correct SpdyFrameType. + // Otherwise returns a best guess at invalid frame type, + // after setting the appropriate SpdyError. + SpdyFrameType ValidateFrameHeader(bool is_control_frame, + int frame_type_field); + // TODO(jgraettinger): To be removed with migration to // SpdyHeadersHandlerInterface. Serializes the last-processed // header block of |hpack_decoder_| as a SPDY3 format block, and @@ -697,10 +709,11 @@ class NET_EXPORT_PRIVATE SpdyFramer { // frame data is streamed to the visitor. static const size_t kControlFrameBufferSize; - // The maximum size of the control frames that we support. - // This limit is arbitrary. We can enforce it here or at the application - // layer. We chose the framing layer, but this can be changed (or removed) - // if necessary later down the line. + // The maximum size of the control frames that we send, including the size of + // the header. This limit is arbitrary. We can enforce it here or at the + // application layer. We chose the framing layer, but this can be changed (or + // removed) if necessary later down the line. + // TODO(diannahu): Rename to make it clear that this limit is for sending. static const size_t kMaxControlFrameSize; SpdyState state_; @@ -742,14 +755,14 @@ class NET_EXPORT_PRIVATE SpdyFramer { // current_frame_buffer_. SpdySettingsScratch settings_scratch_; - scoped_ptr<CharBuffer> altsvc_scratch_; + std::unique_ptr<CharBuffer> altsvc_scratch_; // SPDY header compressors. - scoped_ptr<z_stream> header_compressor_; - scoped_ptr<z_stream> header_decompressor_; + std::unique_ptr<z_stream> header_compressor_; + std::unique_ptr<z_stream> header_decompressor_; - scoped_ptr<HpackEncoder> hpack_encoder_; - scoped_ptr<HpackDecoder> hpack_decoder_; + std::unique_ptr<HpackEncoder> hpack_encoder_; + std::unique_ptr<HpackDecoder> hpack_decoder_; SpdyFramerVisitorInterface* visitor_; SpdyFramerDebugVisitorInterface* debug_visitor_; @@ -789,11 +802,6 @@ class NET_EXPORT_PRIVATE SpdyFramer { // If true, then ProcessInput returns after processing a full frame, // rather than reading all available input. bool process_single_input_frame_ = false; - - // Latched value of --FLAGS_spdy_on_stream_end. - // If true, OnStreamEnd will be called instead of the sentinel call of - // OnStreamFrameData(stream_id, nullptr, 0, true) - bool spdy_on_stream_end_; }; } // namespace net diff --git a/chromium/net/spdy/spdy_framer_test.cc b/chromium/net/spdy/spdy_framer_test.cc index 3c4724eb77b..1ce33951a21 100644 --- a/chromium/net/spdy/spdy_framer_test.cc +++ b/chromium/net/spdy/spdy_framer_test.cc @@ -14,8 +14,9 @@ #include <vector> #include "base/compiler_specific.h" +#include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" +#include "base/strings/string_number_conversions.h" #include "net/quic/quic_flags.h" #include "net/spdy/hpack/hpack_constants.h" #include "net/spdy/mock_spdy_framer_visitor.h" @@ -94,8 +95,7 @@ class SpdyFramerTestUtil { } void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override { + size_t len) override { LOG(FATAL); } @@ -240,7 +240,7 @@ class SpdyFramerTestUtil { private: SpdyMajorVersion version_; - scoped_ptr<char[]> buffer_; + std::unique_ptr<char[]> buffer_; size_t size_; bool finished_; @@ -297,65 +297,58 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, header_buffer_valid_(false) {} void OnError(SpdyFramer* f) override { - LOG(INFO) << "SpdyFramer Error: " - << SpdyFramer::ErrorCodeToString(f->error_code()); + VLOG(1) << "SpdyFramer Error: " + << SpdyFramer::ErrorCodeToString(f->error_code()); ++error_count_; } void OnDataFrameHeader(SpdyStreamId stream_id, size_t length, bool fin) override { + VLOG(1) << "OnDataFrameHeader(" << stream_id << ", " << length << ", " + << fin << ")"; ++data_frame_count_; header_stream_id_ = stream_id; } void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override { + size_t len) override { + VLOG(1) << "OnStreamFrameData(" << stream_id << ", data, " << len << ", " + << ") data:\n" + << base::HexEncode(data, len); EXPECT_EQ(header_stream_id_, stream_id); - if (!FLAGS_spdy_on_stream_end) { - if (len == 0) { - ++end_of_stream_count_; - } - } - data_bytes_ += len; - LOG(INFO) << "OnStreamFrameData(" << stream_id << ", \""; - if (len > 0) { - for (size_t i = 0 ; i < len; ++i) { - LOG(INFO) << std::hex << (0xFF & static_cast<unsigned int>(data[i])) - << std::dec; - } - } - LOG(INFO) << "\", " << len << ")\n"; } void OnStreamEnd(SpdyStreamId stream_id) override { - LOG(INFO) << "OnStreamEnd(" << stream_id << ")"; + VLOG(1) << "OnStreamEnd(" << stream_id << ")"; EXPECT_EQ(header_stream_id_, stream_id); ++end_of_stream_count_; } void OnStreamPadding(SpdyStreamId stream_id, size_t len) override { + VLOG(1) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; EXPECT_EQ(header_stream_id_, stream_id); data_bytes_ += len; - LOG(INFO) << "OnStreamPadding(" << stream_id << ", " << len << ")\n"; } SpdyHeadersHandlerInterface* OnHeaderFrameStart( SpdyStreamId stream_id) override { - LOG(FATAL); + LOG(FATAL) << "OnHeaderFrameStart(" << stream_id << ")"; return nullptr; } void OnHeaderFrameEnd(SpdyStreamId stream_id, bool end_headers) override { - LOG(FATAL); + LOG(FATAL) << "OnHeaderFrameEnd(" << stream_id << ", " << end_headers + << ")"; } bool OnControlFrameHeaderData(SpdyStreamId stream_id, const char* header_data, size_t len) override { + VLOG(1) << "OnControlFrameHeaderData(" << stream_id << ", data, " << len + << ")"; ++control_frame_header_data_count_; CHECK_EQ(header_stream_id_, stream_id); if (len == 0) { @@ -381,6 +374,9 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SpdyPriority priority, bool fin, bool unidirectional) override { + VLOG(1) << "OnSynStream(" << stream_id << ", " << associated_stream_id + << ", " << priority << ", " << (fin ? 1 : 0) << ", " + << (unidirectional ? 1 : 0) << ")"; ++syn_frame_count_; if (framer_.protocol_version() == SPDY3) { InitHeaderStreaming(SYN_STREAM, stream_id); @@ -406,6 +402,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, void OnRstStream(SpdyStreamId stream_id, SpdyRstStreamStatus status) override { + VLOG(1) << "OnRstStream(" << stream_id << ", " << status << ")"; ++fin_frame_count_; } @@ -417,24 +414,31 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, } void OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) override { + VLOG(1) << "OnSetting(" << id << ", " << std::hex << flags << ", " << value + << ")"; ++setting_count_; } void OnSettingsAck() override { + VLOG(1) << "OnSettingsAck"; DCHECK_EQ(HTTP2, framer_.protocol_version()); ++settings_ack_received_; } void OnSettingsEnd() override { + VLOG(1) << "OnSettingsEnd"; if (framer_.protocol_version() == HTTP2) { ++settings_ack_sent_; } } - void OnPing(SpdyPingId unique_id, bool is_ack) override { DLOG(FATAL); } + void OnPing(SpdyPingId unique_id, bool is_ack) override { + LOG(DFATAL) << "OnPing(" << unique_id << ", " << (is_ack ? 1 : 0) << ")"; + } void OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status) override { + VLOG(1) << "OnGoAway(" << last_accepted_stream_id << ", " << status << ")"; ++goaway_count_; } @@ -445,6 +449,9 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, bool exclusive, bool fin, bool end) override { + VLOG(1) << "OnHeaders(" << stream_id << ", " << has_priority << ", " + << priority << ", " << parent_stream_id << ", " << exclusive << ", " + << fin << ", " << end << ")"; ++headers_frame_count_; InitHeaderStreaming(HEADERS, stream_id); if (fin) { @@ -456,6 +463,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, } void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override { + VLOG(1) << "OnWindowUpdate(" << stream_id << ", " << delta_window_size + << ")"; last_window_update_stream_ = stream_id; last_window_update_delta_ = delta_window_size; } @@ -463,6 +472,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, bool end) override { + VLOG(1) << "OnPushPromise(" << stream_id << ", " << promised_stream_id + << ", " << end << ")"; ++push_promise_frame_count_; InitHeaderStreaming(PUSH_PROMISE, stream_id); last_push_promise_stream_ = stream_id; @@ -470,6 +481,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, } void OnContinuation(SpdyStreamId stream_id, bool end) override { + VLOG(1) << "OnContinuation(" << stream_id << ", " << end << ")"; ++continuation_count_; } @@ -477,6 +489,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, StringPiece origin, const SpdyAltSvcWireFormat::AlternativeServiceVector& altsvc_vector) override { + VLOG(1) << "OnAltSvc(" << stream_id << ", \"" << origin + << "\", altsvc_vector)"; test_altsvc_ir_.set_stream_id(stream_id); if (origin.length() > 0) { test_altsvc_ir_.set_origin(origin.as_string()); @@ -492,11 +506,13 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SpdyStreamId parent_stream_id, uint8_t weight, bool exclusive) override { + VLOG(1) << "OnPriority(" << stream_id << ", " << parent_stream_id << ", " + << weight << ", " << (exclusive ? 1 : 0) << ")"; ++priority_count_; } bool OnUnknownFrame(SpdyStreamId stream_id, int frame_type) override { - DLOG(INFO) << "Unknown frame type " << frame_type; + VLOG(1) << "OnUnknownFrame(" << stream_id << ", " << frame_type << ")"; return on_unknown_frame_result_; } @@ -504,6 +520,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, SpdyFrameType type, size_t payload_len, size_t frame_len) override { + VLOG(1) << "OnSendCompressedFrame(" << stream_id << ", " << type << ", " + << payload_len << ", " << frame_len << ")"; last_payload_len_ = payload_len; last_frame_len_ = frame_len; } @@ -511,6 +529,8 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, void OnReceiveCompressedFrame(SpdyStreamId stream_id, SpdyFrameType type, size_t frame_len) override { + VLOG(1) << "OnReceiveCompressedFrame(" << stream_id << ", " << type << ", " + << frame_len << ")"; last_frame_len_ = frame_len; } @@ -563,6 +583,12 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, return SpdyFramer::kMaxControlFrameSize; } + // Largest control frame that the SPDY implementation is willing to receive, + // excluding the size of the header. + static size_t received_control_frame_max_size() { + return kSpdyInitialFrameSizeLimit; + } + static size_t header_data_chunk_max_size() { return SpdyFramer::kHeaderDataChunkMaxSize; } @@ -602,7 +628,7 @@ class TestSpdyVisitor : public SpdyFramerVisitorInterface, size_t last_frame_len_; // Header block streaming state: - scoped_ptr<char[]> header_buffer_; + std::unique_ptr<char[]> header_buffer_; size_t header_buffer_length_; size_t header_buffer_size_; SpdyStreamId header_stream_id_; @@ -803,6 +829,150 @@ TEST_P(SpdyFramerTest, HeaderStreamDependencyValues) { } } +// Test that if we receive a DATA frame with padding length larger than the +// payload length, we set an error of SPDY_INVALID_PADDING +TEST_P(SpdyFramerTest, OversizedDataPaddingError) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // DATA frame with invalid padding length. + // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses + // MSVC, where |char| is signed by default, which would not compile because of + // the element exceeding 127. + unsigned char kH2FrameData[] = { + 0x00, 0x00, 0x05, // Length + 0x00, // Type (DATA) + 0x09, // Flags (PADDED, END_STREAM) + 0x00, 0x00, 0x00, 0x01, // Stream id + 0xFF, // Padding length (here larger than length) + 0x00, 0x00, 0x00, 0x00, // Arbitrary data payload + }; + + SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData), + sizeof(kH2FrameData), false); + + { + testing::InSequence seq; + EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, 1)); + EXPECT_CALL(visitor, OnStreamPadding(1, 1)); + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + } + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_PADDING, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a DATA frame with padding length not larger than the +// payload length, we do not set an error of SPDY_INVALID_PADDING +TEST_P(SpdyFramerTest, CorrectlySizedDataPaddingNoError) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // DATA frame with valid Padding length + char kH2FrameData[] = { + 0x00, 0x00, 0x05, // Length + 0x00, // Type (DATA) + 0x08, // Flags (PADDED) + 0x00, 0x00, 0x00, 0x01, // Stream id + 0x04, // Padding length (here one less than length) + 0x00, 0x00, 0x00, 0x00, // Padding bytes + }; + + SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); + + { + testing::InSequence seq; + EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, false)); + EXPECT_CALL(visitor, OnStreamPadding(1, 1)); + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))).Times(0); + // Note that OnStreamFrameData(1, _, 1)) is never called + // since there is no data, only padding + EXPECT_CALL(visitor, OnStreamPadding(1, 4)); + } + + EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_FALSE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a HEADERS frame with padding length larger than the +// payload length, we set an error of SPDY_INVALID_PADDING +TEST_P(SpdyFramerTest, OversizedHeadersPaddingError) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // HEADERS frame with invalid padding length. + // |kH2FrameData| has to be |unsigned char|, because Chromium on Windows uses + // MSVC, where |char| is signed by default, which would not compile because of + // the element exceeding 127. + unsigned char kH2FrameData[] = { + 0x00, 0x00, 0x05, // Length + 0x01, // Type (HEADERS) + 0x08, // Flags (PADDED) + 0x00, 0x00, 0x00, 0x01, // Stream id + 0xFF, // Padding length (here larger than length) + 0x00, 0x00, 0x00, 0x00, // Arbitrary data payload + }; + + SpdySerializedFrame frame(reinterpret_cast<char*>(kH2FrameData), + sizeof(kH2FrameData), false); + + EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_PADDING, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a HEADERS frame with padding length not larger +// than the payload length, we do not set an error of SPDY_INVALID_PADDING +TEST_P(SpdyFramerTest, CorrectlySizedHeadersPaddingNoError) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // HEADERS frame with invalid Padding length + char kH2FrameData[] = { + 0x00, 0x00, 0x05, // Length + 0x01, // Type (HEADERS) + 0x08, // Flags (PADDED) + 0x00, 0x00, 0x00, 0x01, // Stream id + 0x04, // Padding length + 0x00, 0x00, 0x00, 0x00, // Padding + }; + + SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); + + EXPECT_CALL(visitor, OnHeaders(1, false, 0, 0, false, false, false)); + + EXPECT_EQ(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_FALSE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + // Test that if we receive a SYN_REPLY with stream ID zero, we signal an error // (but don't crash). TEST_P(SpdyFramerTest, SynReplyWithStreamIdZero) { @@ -826,6 +996,29 @@ TEST_P(SpdyFramerTest, SynReplyWithStreamIdZero) { << SpdyFramer::ErrorCodeToString(framer.error_code()); } +// Test that if we receive a DATA with stream ID zero, we signal an error +// (but don't crash). +TEST_P(SpdyFramerTest, DataWithStreamIdZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + const char bytes[] = "hello"; + SpdyDataIR data_ir(0, bytes); + SpdySerializedFrame frame(framer.SerializeData(data_ir)); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + // Test that if we receive a HEADERS with stream ID zero, we signal an error // (but don't crash). TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) { @@ -841,12 +1034,149 @@ TEST_P(SpdyFramerTest, HeadersWithStreamIdZero) { EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); EXPECT_TRUE(framer.HasError()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code()) + if (IsHttp2()) { + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); + } else { + EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); + } +} + +// Test that if we receive a PRIORITY with stream ID zero, we signal an error +// (but don't crash). +TEST_P(SpdyFramerTest, PriorityWithStreamIdZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + SpdyPriorityIR priority_ir(0, 1, 16, true); + SpdySerializedFrame frame(framer.SerializeFrame(priority_ir)); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a RST_STREAM with stream ID zero, we signal an error +// (but don't crash). +TEST_P(SpdyFramerTest, RstStreamWithStreamIdZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + SpdyRstStreamIR rst_stream_ir(0, RST_STREAM_PROTOCOL_ERROR); + SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream_ir)); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a SETTINGS with stream ID other than zero, +// we signal an error (but don't crash). +TEST_P(SpdyFramerTest, SettingsWithStreamIdNotZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // Settings frame with invalid StreamID of 0x01 + char kH2FrameData[] = { + 0x00, 0x00, 0x06, // Length + 0x04, // Type (SETTINGS) + 0x00, // Flags + 0x00, 0x00, 0x00, 0x01, // Stream id + 0x00, 0x04, // Setting id + 0x0a, 0x0b, 0x0c, 0x0d, // Setting value + }; + + SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a GOAWAY with stream ID other than zero, +// we signal an error (but don't crash). +TEST_P(SpdyFramerTest, GoawayWithStreamIdNotZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + // GOAWAY frame with invalid StreamID of 0x01 + char kH2FrameData[] = { + 0x00, 0x00, 0x0a, // Length + 0x07, // Type (GOAWAY) + 0x00, // Flags + 0x00, 0x00, 0x00, 0x01, // Stream id + 0x00, 0x00, 0x00, 0x00, // Last-stream ID + 0x00, 0x00, 0x00, 0x00, // Error code + 0x47, 0x41, // Opaque Description + }; + + SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + +// Test that if we receive a CONTINUATION with stream ID zero, we signal an +// SPDY_INVALID_STREAM_ID. +TEST_P(SpdyFramerTest, ContinuationWithStreamIdZero) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + SpdyContinuationIR continuation(0); + continuation.SetHeader("bar", "foo"); + continuation.SetHeader("foo", "bar"); + continuation.set_end_headers(true); + SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) << SpdyFramer::ErrorCodeToString(framer.error_code()); } // Test that if we receive a PUSH_PROMISE with stream ID zero, we signal an -// error (but don't crash). +// SPDY_INVALID_STREAM_ID. TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) { if (!IsHttp2()) { return; @@ -864,12 +1194,12 @@ TEST_P(SpdyFramerTest, PushPromiseWithStreamIdZero) { EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); EXPECT_TRUE(framer.HasError()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, framer.error_code()) + EXPECT_EQ(SpdyFramer::SPDY_INVALID_STREAM_ID, framer.error_code()) << SpdyFramer::ErrorCodeToString(framer.error_code()); } // Test that if we receive a PUSH_PROMISE with promised stream ID zero, we -// signal an error (but don't crash). +// signal SPDY_INVALID_STREAM_ID. TEST_P(SpdyFramerTest, PushPromiseWithPromisedStreamIdZero) { if (!IsHttp2()) { return; @@ -983,7 +1313,7 @@ TEST_P(SpdyFramerTest, BasicCompression) { return; } - scoped_ptr<TestSpdyVisitor> visitor(new TestSpdyVisitor(spdy_version_)); + std::unique_ptr<TestSpdyVisitor> visitor(new TestSpdyVisitor(spdy_version_)); SpdyFramer framer(spdy_version_); framer.set_debug_visitor(visitor.get()); SpdySynStreamIR syn_stream(1); @@ -1165,12 +1495,10 @@ TEST_P(SpdyFramerTest, Basic) { 0x00, 0x00, 0x00, 0x00, 0x03, - 0x00, 0x00, 0x0f, 0x03, // RST_STREAM on Stream #3 + 0x00, 0x00, 0x04, 0x03, // RST_STREAM on Stream #3 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // RST_STREAM_CANCEL - 0x08, 0x52, 0x45, 0x53, // opaque data - 0x45, 0x54, 0x53, 0x54, - 0x52, 0x45, 0x41, 0x4d, + 0x08, }; TestSpdyVisitor visitor(spdy_version_); @@ -1192,8 +1520,7 @@ TEST_P(SpdyFramerTest, Basic) { } else { EXPECT_EQ(3, visitor.headers_frame_count_); EXPECT_EQ(0, visitor.syn_frame_count_); - StringPiece reset_stream = "RESETSTREAM"; - EXPECT_EQ(reset_stream, visitor.fin_opaque_data_); + EXPECT_TRUE(visitor.fin_opaque_data_.empty()); } EXPECT_EQ(0, visitor.fin_flag_count_); @@ -1753,7 +2080,7 @@ TEST_P(SpdyFramerTest, CreateDataFrame) { }; const int kFrameSize = arraysize(kFrameHeader) + kDataSize; - scoped_ptr<unsigned char[]> expected_frame_data( + std::unique_ptr<unsigned char[]> expected_frame_data( new unsigned char[kFrameSize]); memcpy(expected_frame_data.get(), kFrameHeader, arraysize(kFrameHeader)); memset(expected_frame_data.get() + arraysize(kFrameHeader), 'A', kDataSize); @@ -2806,17 +3133,19 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { const char kDescription[] = "PUSH_PROMISE frame without padding"; const unsigned char kFrameData[] = { - 0x00, 0x00, 0x16, 0x05, // PUSH_PROMISE - 0x04, 0x00, 0x00, 0x00, // END_HEADERS - 0x2a, 0x00, 0x00, 0x00, // Stream 42 - 0x39, 0x00, 0x03, 0x62, // Promised stream 57, @.b + 0x00, 0x00, 0x16, // Length 22 + 0x05, // PUSH_PROMISE + 0x04, // END_HEADERS + 0x00, 0x00, 0x00, 0x29, // Stream 41 + 0x00, 0x00, 0x00, 0x3a, // Promised stream 58 + 0x00, 0x03, 0x62, // @.b 0x61, 0x72, 0x03, 0x66, // ar.f 0x6f, 0x6f, 0x00, 0x03, // oo@. 0x66, 0x6f, 0x6f, 0x03, // foo. 0x62, 0x61, 0x72, // bar }; - SpdyPushPromiseIR push_promise(42, 57); + SpdyPushPromiseIR push_promise(41, 58); push_promise.SetHeader("bar", "foo"); push_promise.SetHeader("foo", "bar"); SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); @@ -2830,17 +3159,20 @@ TEST_P(SpdyFramerTest, CreatePushPromiseUncompressed) { const char kDescription[] = "PUSH_PROMISE frame with one byte of padding"; const unsigned char kFrameData[] = { - 0x00, 0x00, 0x17, 0x05, // PUSH_PROMISE - 0x0c, 0x00, 0x00, 0x00, // END_HEADERS | PADDED - 0x2a, 0x00, 0x00, 0x00, // Stream 42, Pad length field - 0x00, 0x39, 0x00, 0x03, // Promised stream 57 + 0x00, 0x00, 0x17, + 0x05, // PUSH_PROMISE + 0x0c, // END_HEADERS | PADDED + 0x00, 0x00, 0x00, 0x29, // Stream 41, + 0x00, // Pad length field + 0x00, 0x00, 0x00, 0x3a, // Promised stream 58 + 0x00, 0x03, // @. 0x62, 0x61, 0x72, 0x03, // bar. 0x66, 0x6f, 0x6f, 0x00, // foo@ 0x03, 0x66, 0x6f, 0x6f, // .foo 0x03, 0x62, 0x61, 0x72, // .bar }; - SpdyPushPromiseIR push_promise(42, 57); + SpdyPushPromiseIR push_promise(41, 58); push_promise.set_padding_len(1); push_promise.SetHeader("bar", "foo"); push_promise.SetHeader("foo", "bar"); @@ -2934,6 +3266,39 @@ TEST_P(SpdyFramerTest, CreateContinuationUncompressed) { CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData)); } +// Test that if we send an unexpected CONTINUATION +// we signal an error (but don't crash). +TEST_P(SpdyFramerTest, SendUnexpectedContinuation) { + if (!IsHttp2()) { + return; + } + + testing::StrictMock<test::MockSpdyFramerVisitor> visitor; + SpdyFramer framer(spdy_version_); + framer.set_visitor(&visitor); + + char kH2FrameData[] = { + 0x00, 0x00, 0x12, // Length + 0x09, // Type (CONTINUATION) + 0x04, // Flags (end_headers) + 0x00, 0x00, 0x00, 0x2a, // Stream 42 + 0x00, 0x03, 0x62, // @.b + 0x61, 0x72, 0x03, 0x66, // ar.f + 0x6f, 0x6f, 0x00, 0x03, // oo@. + 0x66, 0x6f, 0x6f, 0x03, // foo. + 0x62, 0x61, 0x72, // bar + }; + + SpdySerializedFrame frame(kH2FrameData, sizeof(kH2FrameData), false); + + // We shouldn't have to read the whole frame before we signal an error. + EXPECT_CALL(visitor, OnError(testing::Eq(&framer))); + EXPECT_GT(frame.size(), framer.ProcessInput(frame.data(), frame.size())); + EXPECT_TRUE(framer.HasError()); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); +} + TEST_P(SpdyFramerTest, CreatePushPromiseThenContinuationUncompressed) { if (!IsHttp2()) { return; @@ -3046,20 +3411,19 @@ TEST_P(SpdyFramerTest, CreateAltSvc) { const char kType = static_cast<unsigned char>( SpdyConstants::SerializeFrameType(spdy_version_, ALTSVC)); const unsigned char kFrameData[] = { - 0x00, 0x00, 0x53, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o', + 0x00, 0x00, 0x49, kType, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x06, 'o', 'r', 'i', 'g', 'i', 'n', 'p', 'i', 'd', '1', '=', '"', 'h', 'o', 's', 't', ':', '4', '4', '3', '"', ';', ' ', 'm', 'a', '=', '5', ',', 'p', '%', '2', '2', '%', '3', 'D', 'i', '%', '3', 'A', 'd', '=', '"', 'h', '_', '\\', '\\', 'o', '\\', '"', 's', 't', ':', '1', '2', '3', '"', ';', ' ', 'm', 'a', '=', - '4', '2', ';', ' ', 'p', '=', '"', '0', '.', '2', '0', '"', - ';', ' ', 'v', '=', '"', '2', '4', '"'}; + '4', '2', ';', ' ', 'v', '=', '"', '2', '4', '"'}; SpdyAltSvcIR altsvc_ir(3); altsvc_ir.set_origin("origin"); altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService( - "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector{})); + "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector())); altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService( - "p\"=i:d", "h_\\o\"st", 123, 42, 0.2, + "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24})); SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir)); CompareFrame(kDescription, frame, kFrameData, arraysize(kFrameData)); @@ -3217,7 +3581,7 @@ TEST_P(SpdyFramerTest, ControlFrameAtMaxSizeLimit) { EXPECT_LT(kBigValueSize, visitor.header_buffer_length_); } -TEST_P(SpdyFramerTest, ControlFrameMaximumSize) { +TEST_P(SpdyFramerTest, ControlFrameTooLarge) { if (!IsSpdy3()) { // TODO(jgraettinger): This test setup doesn't work with HPACK. return; @@ -3232,26 +3596,34 @@ TEST_P(SpdyFramerTest, ControlFrameMaximumSize) { syn_stream.set_priority(1); SpdySerializedFrame control_frame(framer.SerializeSynStream(syn_stream)); const size_t kBigValueSize = - SpdyConstants::GetFrameMaximumSize(spdy_version_) - control_frame.size(); + TestSpdyVisitor::received_control_frame_max_size() + + SpdyConstants::GetControlFrameHeaderSize(spdy_version_) - + control_frame.size() + 1; // Create a frame at exatly that size. string big_value(kBigValueSize, 'x'); syn_stream.SetHeader("aa", big_value); - // Upstream branches here and wraps HTTP/2 with EXPECT_DEBUG_DFATAL. We - // neither support that in Chromium, nor do we use the same DFATAL (see - // SpdyFrameBuilder::WriteFramePrefix()). - control_frame = framer.SerializeSynStream(syn_stream); - - EXPECT_EQ(SpdyConstants::GetFrameMaximumSize(spdy_version_), + if (IsSpdy3()) { + control_frame = framer.SerializeSynStream(syn_stream); + } else { + EXPECT_SPDY_BUG({ control_frame = framer.SerializeSynStream(syn_stream); }, + "Serializing frame over-capacity."); + } + EXPECT_EQ(TestSpdyVisitor::received_control_frame_max_size() + + SpdyConstants::GetControlFrameHeaderSize(spdy_version_) + 1, control_frame.size()); TestSpdyVisitor visitor(spdy_version_); visitor.SimulateInFramer( reinterpret_cast<unsigned char*>(control_frame.data()), control_frame.size()); - EXPECT_TRUE(visitor.header_buffer_valid_); - EXPECT_EQ(0, visitor.error_count_); - EXPECT_EQ(1, visitor.syn_frame_count_); + EXPECT_FALSE(visitor.header_buffer_valid_); + EXPECT_EQ(1, visitor.error_count_); + EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE, + visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); + EXPECT_EQ(0, visitor.syn_frame_count_); + EXPECT_EQ(0u, visitor.header_buffer_length_); } TEST_P(SpdyFramerTest, TooLargeHeadersFrameUsesContinuation) { @@ -3339,7 +3711,7 @@ TEST_P(SpdyFramerTest, ControlFrameMuchTooLarge) { EXPECT_EQ(1, visitor.error_count_); EXPECT_EQ(SpdyFramer::SPDY_CONTROL_PAYLOAD_TOO_LARGE, visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); // The framer should have stoped delivering chunks after the visitor // signaled "stop" by returning false from OnControlFrameHeaderData(). @@ -3378,7 +3750,7 @@ TEST_P(SpdyFramerTest, DecompressCorruptHeaderBlock) { control_frame.size()); EXPECT_EQ(1, visitor.error_count_); EXPECT_EQ(SpdyFramer::SPDY_DECOMPRESS_FAILURE, visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(0u, visitor.header_buffer_length_); } @@ -3426,7 +3798,7 @@ TEST_P(SpdyFramerTest, ControlFrameSizesAreValidated) { EXPECT_EQ(1, visitor.error_count_); // This generated an error. EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(0, visitor.goaway_count_); // Frame not parsed. } @@ -3710,14 +4082,14 @@ TEST_P(SpdyFramerTest, ProcessDataFrameWithPadding) { bytes_consumed += 1; // Send the first two bytes of the data payload, i.e., "he". - EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2, false)); + EXPECT_CALL(visitor, OnStreamFrameData(1, _, 2)); CHECK_EQ(2u, framer.ProcessInput(frame.data() + bytes_consumed, 2)); CHECK_EQ(framer.state(), SpdyFramer::SPDY_FORWARD_STREAM_FRAME); CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR); bytes_consumed += 2; // Send the rest three bytes of the data payload, i.e., "llo". - EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3, false)); + EXPECT_CALL(visitor, OnStreamFrameData(1, _, 3)); CHECK_EQ(3u, framer.ProcessInput(frame.data() + bytes_consumed, 3)); CHECK_EQ(framer.state(), SpdyFramer::SPDY_CONSUME_PADDING); CHECK_EQ(framer.error_code(), SpdyFramer::SPDY_NO_ERROR); @@ -3866,54 +4238,73 @@ TEST_P(SpdyFramerTest, ReadPushPromiseWithContinuation) { testing::Pair("name", "value"))); } -TEST_P(SpdyFramerTest, ReadContinuationWithWrongStreamId) { +// Receiving an unknown frame when a continuation is expected should +// result in a SPDY_UNEXPECTED_FRAME error +TEST_P(SpdyFramerTest, ReceiveUnknownMidContinuation) { if (!IsHttp2()) { return; } const unsigned char kInput[] = { - 0x00, 0x00, 0x10, 0x01, 0x00, // HEADERS - 0x00, 0x00, 0x00, 0x01, // Stream 1 - 0x00, 0x06, 0x63, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, - 0x07, 0x66, 0x6f, 0x6f, - 0x3d, 0x62, 0x61, 0x72, - - 0x00, 0x00, 0x14, 0x09, 0x00, // CONTINUATION - 0x00, 0x00, 0x00, 0x02, // Stream 2 - 0x00, 0x06, 0x63, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, - 0x08, 0x62, 0x61, 0x7a, - 0x3d, 0x62, 0x69, 0x6e, - 0x67, 0x00, 0x06, 0x63, + 0x00, 0x00, 0x10, // Length + 0x01, // Type (HEADERS) + 0x00, // Flags (none, thus expect CONTINUATION) + 0x00, 0x00, 0x00, 0x01, // Stream 1 + 0x00, 0x06, 0x63, 0x6f, // Header block fragment + 0x6f, 0x6b, 0x69, 0x65, // Header block fragment + 0x07, 0x66, 0x6f, 0x6f, // Header block fragment + 0x3d, 0x62, 0x61, 0x72, // Header block fragment + + 0x00, 0x00, 0x14, // Length + 0xa9, // Type (UNKNOWN) + 0x00, // Flags (none) + 0x00, 0x00, 0x00, 0x01, // Stream 1 + 0x00, 0x06, 0x63, 0x6f, // Payload + 0x6f, 0x6b, 0x69, 0x65, // Payload + 0x08, 0x62, 0x61, 0x7a, // Payload + 0x3d, 0x62, 0x69, 0x6e, // Payload + 0x67, 0x00, 0x06, 0x63, // Payload }; SpdyFramer framer(spdy_version_); TestSpdyVisitor visitor(spdy_version_); + // Assume the unknown frame is allowed + visitor.on_unknown_frame_result_ = true; framer.set_visitor(&visitor); visitor.SimulateInFramer(kInput, sizeof(kInput)); EXPECT_EQ(1, visitor.error_count_); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME, - visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(1, visitor.headers_frame_count_); EXPECT_EQ(0, visitor.continuation_count_); EXPECT_EQ(0u, visitor.header_buffer_length_); } -TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) { +TEST_P(SpdyFramerTest, ReceiveContinuationOnWrongStream) { if (!IsHttp2()) { return; } const unsigned char kInput[] = { - 0x00, 0x00, 0x18, 0x09, 0x00, // CONTINUATION - 0x00, 0x00, 0x00, 0x01, // Stream 1 - 0x00, 0x06, 0x63, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, - 0x07, 0x66, 0x6f, 0x6f, - 0x3d, 0x62, 0x61, 0x72, + 0x00, 0x00, 0x10, // Length + 0x01, // Type (HEADERS) + 0x00, // Flags (none, thus expect CONTINUATION) + 0x00, 0x00, 0x00, 0x01, // Stream 1 + 0x00, 0x06, 0x63, 0x6f, // Header block fragment + 0x6f, 0x6b, 0x69, 0x65, // Header block fragment + 0x07, 0x66, 0x6f, 0x6f, // Header block fragment + 0x3d, 0x62, 0x61, 0x72, // Header block fragment + + 0x00, 0x00, 0x14, // Length + 0x09, // Type (CONTINUATION) + 0x00, // Flags (none) + 0x00, 0x00, 0x00, 0x02, // Stream 2 + 0x00, 0x06, 0x63, 0x6f, // Header block fragment + 0x6f, 0x6b, 0x69, 0x65, // Header block fragment + 0x08, 0x62, 0x61, 0x7a, // Header block fragment + 0x3d, 0x62, 0x69, 0x6e, // Header block fragment + 0x67, 0x00, 0x06, 0x63, // Header block fragment }; SpdyFramer framer(spdy_version_); @@ -3922,29 +4313,25 @@ TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) { visitor.SimulateInFramer(kInput, sizeof(kInput)); EXPECT_EQ(1, visitor.error_count_); - EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, - visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); + EXPECT_EQ(1, visitor.headers_frame_count_); EXPECT_EQ(0, visitor.continuation_count_); EXPECT_EQ(0u, visitor.header_buffer_length_); } -TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) { +TEST_P(SpdyFramerTest, ReadContinuationOutOfOrder) { if (!IsHttp2()) { return; } const unsigned char kInput[] = { - 0x00, 0x00, 0x10, 0x01, 0x00, // HEADERS + 0x00, 0x00, 0x18, 0x09, 0x00, // CONTINUATION 0x00, 0x00, 0x00, 0x01, // Stream 1 0x00, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x07, 0x66, 0x6f, 0x6f, 0x3d, 0x62, 0x61, 0x72, - - 0x00, 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1 - 0x00, 0x00, 0x00, 0x04, - 0xde, 0xad, 0xbe, 0xef, }; SpdyFramer framer(spdy_version_); @@ -3953,35 +4340,28 @@ TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) { visitor.SimulateInFramer(kInput, sizeof(kInput)); EXPECT_EQ(1, visitor.error_count_); - EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, - visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - EXPECT_EQ(1, visitor.headers_frame_count_); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(0, visitor.continuation_count_); EXPECT_EQ(0u, visitor.header_buffer_length_); - EXPECT_EQ(0, visitor.data_frame_count_); } -TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) { +TEST_P(SpdyFramerTest, ExpectContinuationReceiveData) { if (!IsHttp2()) { return; } const unsigned char kInput[] = { - 0x00, 0x00, 0x18, 0x01, 0x00, // HEADERS + 0x00, 0x00, 0x10, 0x01, 0x00, // HEADERS 0x00, 0x00, 0x00, 0x01, // Stream 1 0x00, 0x06, 0x63, 0x6f, 0x6f, 0x6b, 0x69, 0x65, 0x07, 0x66, 0x6f, 0x6f, 0x3d, 0x62, 0x61, 0x72, - 0x00, 0x00, 0x1c, 0x08, 0x00, // HEADERS - 0x00, 0x00, 0x00, 0x01, // Stream 1 - 0x00, 0x06, 0x63, 0x6f, // (Note this is a valid continued encoding). - 0x6f, 0x6b, 0x69, 0x65, - 0x08, 0x62, 0x61, 0x7a, - 0x3d, 0x62, 0x69, 0x6e, - 0x67, 0x00, 0x06, 0x63, + 0x00, 0x00, 0x00, 0x00, 0x01, // DATA on Stream #1 + 0x00, 0x00, 0x00, 0x04, + 0xde, 0xad, 0xbe, 0xef, }; SpdyFramer framer(spdy_version_); @@ -3990,62 +4370,51 @@ TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) { visitor.SimulateInFramer(kInput, sizeof(kInput)); EXPECT_EQ(1, visitor.error_count_); - EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, - visitor.framer_.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(1, visitor.headers_frame_count_); EXPECT_EQ(0, visitor.continuation_count_); EXPECT_EQ(0u, visitor.header_buffer_length_); EXPECT_EQ(0, visitor.data_frame_count_); } -TEST_P(SpdyFramerTest, EndSegmentOnDataFrame) { - if (!IsHttp2()) { - return; - } - - const unsigned char kInput[] = { - 0x00, 0x00, 0x0c, 0x00, 0x02, // DATA: END_SEGMENT - 0x00, 0x00, 0x00, 0x01, // Stream 1 - 0xde, 0xad, 0xbe, 0xef, - 0xde, 0xad, 0xbe, 0xef, - 0xde, 0xad, 0xbe, 0xef, - }; - - TestSpdyVisitor visitor(spdy_version_); - visitor.SimulateInFramer(kInput, sizeof(kInput)); - - // TODO(jgraettinger): Verify END_SEGMENT when support is added. - EXPECT_EQ(0, visitor.error_count_); - EXPECT_EQ(12, visitor.data_bytes_); - EXPECT_EQ(0, visitor.fin_frame_count_); - EXPECT_EQ(0, visitor.fin_flag_count_); -} - -TEST_P(SpdyFramerTest, EndSegmentOnHeadersFrame) { +TEST_P(SpdyFramerTest, ExpectContinuationReceiveControlFrame) { if (!IsHttp2()) { return; } const unsigned char kInput[] = { - 0x00, 0x00, 0x10, 0x01, 0x06, // HEADERS: END_SEGMENT | END_HEADERS - 0x00, 0x00, 0x00, 0x01, // Stream 1 - 0x00, 0x06, 0x63, 0x6f, - 0x6f, 0x6b, 0x69, 0x65, - 0x07, 0x66, 0x6f, 0x6f, - 0x3d, 0x62, 0x61, 0x72, + 0x00, 0x00, 0x10, // Payload Size + 0x01, // HEADERS + 0x00, // No flags (!END_HEADERS) + 0x00, 0x00, 0x00, 0x01, // Stream 1 + 0x00, 0x06, 0x63, 0x6f, // Payload + 0x6f, 0x6b, 0x69, 0x65, // Payload + 0x07, 0x66, 0x6f, 0x6f, // Payload + 0x3d, 0x62, 0x61, 0x72, // Payload + + 0x00, 0x00, 0x10, // Payload Size + 0x01, // HEADERS + 0x00, // No flags (!END_HEADERS) + 0x00, 0x00, 0x00, 0x01, // Stream 1 + 0x00, 0x06, 0x63, 0x6f, // Payload + 0x6f, 0x6b, 0x69, 0x65, // Payload + 0x07, 0x66, 0x6f, 0x6f, // Payload + 0x3d, 0x62, 0x61, 0x72, // Payload }; + SpdyFramer framer(spdy_version_); TestSpdyVisitor visitor(spdy_version_); + framer.set_visitor(&visitor); visitor.SimulateInFramer(kInput, sizeof(kInput)); - // TODO(jgraettinger): Verify END_SEGMENT when support is added. - EXPECT_EQ(0, visitor.error_count_); + EXPECT_EQ(1, visitor.error_count_); + EXPECT_EQ(SpdyFramer::SPDY_UNEXPECTED_FRAME, visitor.framer_.error_code()) + << SpdyFramer::ErrorCodeToString(visitor.framer_.error_code()); EXPECT_EQ(1, visitor.headers_frame_count_); - EXPECT_EQ(1, visitor.zero_length_control_frame_header_data_count_); - - EXPECT_THAT(visitor.headers_, - testing::ElementsAre(testing::Pair("cookie", "foo=bar"))); + EXPECT_EQ(0, visitor.continuation_count_); + EXPECT_EQ(0u, visitor.header_buffer_length_); + EXPECT_EQ(0, visitor.data_frame_count_); } TEST_P(SpdyFramerTest, ReadGarbage) { @@ -4067,10 +4436,12 @@ TEST_P(SpdyFramerTest, ReadUnknownExtensionFrame) { // The unrecognized frame type should still have a valid length. const unsigned char unknown_frame[] = { - 0x00, 0x00, 0x08, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, - 0xff, 0xff, 0xff, 0xff, + 0x00, 0x00, 0x08, // Payload length 8 + 0xff, // Frame type 0xff + 0xff, // Flags 0xff + 0xff, 0xff, 0xff, 0xff, // R=1 and Stream Id 0x7fffffff + 0xff, 0xff, 0xff, 0xff, // Payload + 0xff, 0xff, 0xff, 0xff, // Payload }; TestSpdyVisitor visitor(spdy_version_); @@ -4225,6 +4596,8 @@ TEST_P(SpdyFramerTest, StateToStringTest) { TEST_P(SpdyFramerTest, ErrorCodeToStringTest) { EXPECT_STREQ("NO_ERROR", SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_NO_ERROR)); + EXPECT_STREQ("INVALID_STREAM_ID", SpdyFramer::ErrorCodeToString( + SpdyFramer::SPDY_INVALID_STREAM_ID)); EXPECT_STREQ("INVALID_CONTROL_FRAME", SpdyFramer::ErrorCodeToString( SpdyFramer::SPDY_INVALID_CONTROL_FRAME)); @@ -4246,6 +4619,8 @@ TEST_P(SpdyFramerTest, ErrorCodeToStringTest) { EXPECT_STREQ("COMPRESS_FAILURE", SpdyFramer::ErrorCodeToString( SpdyFramer::SPDY_COMPRESS_FAILURE)); + EXPECT_STREQ("SPDY_INVALID_PADDING", + SpdyFramer::ErrorCodeToString(SpdyFramer::SPDY_INVALID_PADDING)); EXPECT_STREQ("SPDY_INVALID_DATA_FRAME_FLAGS", SpdyFramer::ErrorCodeToString( SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS)); @@ -4335,15 +4710,14 @@ TEST_P(SpdyFramerTest, CatchProbableHttpResponse) { } TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) { - FLAGS_spdy_on_stream_end = true; - if (!IsSpdy3()) { return; } uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4357,7 +4731,7 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) { EXPECT_CALL(visitor, OnError(_)); } else { EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN)); - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false)); + EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5)); if (flags & DATA_FLAG_FIN) { EXPECT_CALL(visitor, OnStreamEnd(_)); } @@ -4376,62 +4750,17 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV2V3) { } while (++flags != 0); } -TEST_P(SpdyFramerTest, DataFrameFlagsV2V3disabled) { - FLAGS_spdy_on_stream_end = false; - - if (!IsSpdy3()) { - return; - } - - uint8_t flags = 0; - do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - - SpdyDataIR data_ir(1, "hello"); - SpdySerializedFrame frame(framer.SerializeData(data_ir)); - SetFrameFlags(&frame, flags, spdy_version_); - - if (flags & ~DATA_FLAG_FIN) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN)); - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false)); - if (flags & DATA_FLAG_FIN) { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)); - } - } - - framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~DATA_FLAG_FIN) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } - } while (++flags != 0); -} - TEST_P(SpdyFramerTest, DataFrameFlagsV4) { - FLAGS_spdy_on_stream_end = true; - if (!IsHttp2()) { return; } - uint8_t valid_data_flags = - DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED; + uint8_t valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED; uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4446,12 +4775,13 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) { } else { EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN)); if (flags & DATA_FLAG_PADDED) { - // The first byte of payload is parsed as padding length. + // The first byte of payload is parsed as padding length, but 'h' + // (0x68) is too large a padding length for a 5 byte payload. EXPECT_CALL(visitor, OnStreamPadding(_, 1)); // Expect Error since the frame ends prematurely. EXPECT_CALL(visitor, OnError(_)); } else { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false)); + EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5)); if (flags & DATA_FLAG_FIN) { EXPECT_CALL(visitor, OnStreamEnd(_)); } @@ -4459,61 +4789,13 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4) { } framer.ProcessInput(frame.data(), frame.size()); - if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PADDED)) { + if (flags & ~valid_data_flags) { EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code()) << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } - } while (++flags != 0); -} - -TEST_P(SpdyFramerTest, DataFrameFlagsV4disabled) { - FLAGS_spdy_on_stream_end = false; - - if (!IsHttp2()) { - return; - } - - uint8_t valid_data_flags = - DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED; - - uint8_t flags = 0; - do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - - SpdyDataIR data_ir(1, "hello"); - SpdySerializedFrame frame(framer.SerializeData(data_ir)); - SetFrameFlags(&frame, flags, spdy_version_); - - if (flags & ~valid_data_flags) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnDataFrameHeader(1, 5, flags & DATA_FLAG_FIN)); - if (flags & DATA_FLAG_PADDED) { - // The first byte of payload is parsed as padding length. - EXPECT_CALL(visitor, OnStreamPadding(_, 1)); - // Expect Error since the frame ends prematurely. - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 5, false)); - if (flags & DATA_FLAG_FIN) { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)); - } - } - } - - framer.ProcessInput(frame.data(), frame.size()); - if ((flags & ~valid_data_flags) || (flags & DATA_FLAG_PADDED)) { + } else if (flags & DATA_FLAG_PADDED) { EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS, framer.error_code()) + EXPECT_EQ(SpdyFramer::SPDY_INVALID_PADDING, framer.error_code()) << SpdyFramer::ErrorCodeToString(framer.error_code()); } else { EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); @@ -4524,15 +4806,14 @@ TEST_P(SpdyFramerTest, DataFrameFlagsV4disabled) { } TEST_P(SpdyFramerTest, SynStreamFrameFlags) { - FLAGS_spdy_on_stream_end = true; - if (!IsSpdy3()) { return; } uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; testing::StrictMock<test::MockDebugVisitor> debug_visitor; @@ -4579,72 +4860,15 @@ TEST_P(SpdyFramerTest, SynStreamFrameFlags) { } while (++flags != 0); } -TEST_P(SpdyFramerTest, SynStreamFrameFlagsDisabled) { - FLAGS_spdy_on_stream_end = false; - - if (!IsSpdy3()) { - return; - } - - uint8_t flags = 0; - do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - testing::StrictMock<test::MockDebugVisitor> debug_visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - framer.set_debug_visitor(&debug_visitor); - - EXPECT_CALL(debug_visitor, OnSendCompressedFrame(8, SYN_STREAM, _, _)); - - SpdySynStreamIR syn_stream(8); - syn_stream.set_associated_to_stream_id(3); - syn_stream.set_priority(1); - syn_stream.SetHeader("foo", "bar"); - SpdySerializedFrame frame(framer.SerializeSynStream(syn_stream)); - SetFrameFlags(&frame, flags, spdy_version_); - - if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(8, SYN_STREAM, _)); - EXPECT_CALL(visitor, OnSynStream(8, 3, 1, flags & CONTROL_FLAG_FIN, - flags & CONTROL_FLAG_UNIDIRECTIONAL)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(8, _, _)) - .WillRepeatedly(testing::Return(true)); - if (flags & DATA_FLAG_FIN) { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)); - } else { - // Do not close the stream if we are expecting a CONTINUATION frame. - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)).Times(0); - } - } - - framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } - } while (++flags != 0); -} - TEST_P(SpdyFramerTest, SynReplyFrameFlags) { - FLAGS_spdy_on_stream_end = true; - if (!IsSpdy3()) { return; } uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4680,55 +4904,11 @@ TEST_P(SpdyFramerTest, SynReplyFrameFlags) { } while (++flags != 0); } -TEST_P(SpdyFramerTest, SynReplyFrameFlagsDisabled) { - FLAGS_spdy_on_stream_end = false; - - if (!IsSpdy3()) { - return; - } - - uint8_t flags = 0; - do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - - SpdySynReplyIR syn_reply(37); - syn_reply.SetHeader("foo", "bar"); - SpdySerializedFrame frame(framer.SerializeSynReply(syn_reply)); - SetFrameFlags(&frame, flags, spdy_version_); - - if (flags & ~CONTROL_FLAG_FIN) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnSynReply(37, flags & CONTROL_FLAG_FIN)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(37, _, _)) - .WillRepeatedly(testing::Return(true)); - if (flags & DATA_FLAG_FIN) { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)); - } - } - - framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~CONTROL_FLAG_FIN) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } - } while (++flags != 0); -} - TEST_P(SpdyFramerTest, RstStreamFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4738,23 +4918,13 @@ TEST_P(SpdyFramerTest, RstStreamFrameFlags) { SpdySerializedFrame frame(framer.SerializeRstStream(rst_stream)); SetFrameFlags(&frame, flags, spdy_version_); - if (flags != 0) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnRstStream(13, RST_STREAM_CANCEL)); - } + EXPECT_CALL(visitor, OnRstStream(13, RST_STREAM_CANCEL)); framer.ProcessInput(frame.data(), frame.size()); - if (flags != 0) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } @@ -4765,7 +4935,8 @@ TEST_P(SpdyFramerTest, SettingsFrameFlagsOldFormat) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4810,7 +4981,8 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4821,7 +4993,7 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) { SpdySerializedFrame frame(framer.SerializeSettings(settings_ir)); SetFrameFlags(&frame, flags, spdy_version_); - if (flags != 0) { + if (flags & SETTINGS_FLAG_ACK) { EXPECT_CALL(visitor, OnError(_)); } else { EXPECT_CALL(visitor, OnSettings(flags & SETTINGS_FLAG_ACK)); @@ -4830,12 +5002,7 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) { } framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~SETTINGS_FLAG_ACK) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else if (flags & SETTINGS_FLAG_ACK) { + if (flags & SETTINGS_FLAG_ACK) { // The frame is invalid because ACK frames should have no payload. EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_SIZE, @@ -4852,7 +5019,8 @@ TEST_P(SpdyFramerTest, SettingsFrameFlags) { TEST_P(SpdyFramerTest, GoawayFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4862,32 +5030,20 @@ TEST_P(SpdyFramerTest, GoawayFrameFlags) { SpdySerializedFrame frame(framer.SerializeGoAway(goaway_ir)); SetFrameFlags(&frame, flags, spdy_version_); - if (flags != 0) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnGoAway(97, GOAWAY_OK)); - } + EXPECT_CALL(visitor, OnGoAway(97, GOAWAY_OK)); framer.ProcessInput(frame.data(), frame.size()); - if (flags != 0) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } TEST_P(SpdyFramerTest, HeadersFrameFlags) { - FLAGS_spdy_on_stream_end = true; - uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -4910,164 +5066,44 @@ TEST_P(SpdyFramerTest, HeadersFrameFlags) { } SetFrameFlags(&frame, set_flags, spdy_version_); - if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) { - EXPECT_CALL(visitor, OnError(_)); - } else if (IsHttp2() && - flags & - ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS | - HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED | - HEADERS_FLAG_PRIORITY)) { - EXPECT_CALL(visitor, OnError(_)); - } else { - // Expected callback values - SpdyStreamId stream_id = 57; - bool has_priority = false; - SpdyPriority priority = 0; - SpdyStreamId parent_stream_id = 0; - bool exclusive = false; - bool fin = flags & CONTROL_FLAG_FIN; - bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS); - if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) { - has_priority = true; - priority = 3; - parent_stream_id = 5; - exclusive = true; - } - EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority, - parent_stream_id, exclusive, fin, end)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _)) - .WillRepeatedly(testing::Return(true)); - if (flags & DATA_FLAG_FIN && - (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) { - EXPECT_CALL(visitor, OnStreamEnd(_)); - } else { - // Do not close the stream if we are expecting a CONTINUATION frame. - EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); - } + // Expected callback values + SpdyStreamId stream_id = 57; + bool has_priority = false; + SpdyPriority priority = 0; + SpdyStreamId parent_stream_id = 0; + bool exclusive = false; + bool fin = flags & CONTROL_FLAG_FIN; + bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS); + if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) { + has_priority = true; + priority = 3; + parent_stream_id = 5; + exclusive = true; } - - framer.ProcessInput(frame.data(), frame.size()); - if (IsSpdy3() && flags & ~CONTROL_FLAG_FIN) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else if (IsHttp2() && - flags & - ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS | - HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED | - HEADERS_FLAG_PRIORITY)) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else if (IsHttp2() && ~(flags & HEADERS_FLAG_END_HEADERS)) { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); + EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority, + parent_stream_id, exclusive, fin, end)); + EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _)) + .WillRepeatedly(testing::Return(true)); + if (flags & DATA_FLAG_FIN && + (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) { + EXPECT_CALL(visitor, OnStreamEnd(_)); } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } - } while (++flags != 0); -} - -TEST_P(SpdyFramerTest, HeadersFrameFlagsDisabled) { - FLAGS_spdy_on_stream_end = false; - - uint8_t flags = 0; - do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); - - testing::StrictMock<test::MockSpdyFramerVisitor> visitor; - SpdyFramer framer(spdy_version_); - framer.set_visitor(&visitor); - - SpdyHeadersIR headers_ir(57); - if (IsHttp2() && (flags & HEADERS_FLAG_PRIORITY)) { - headers_ir.set_priority(3); - headers_ir.set_has_priority(true); - headers_ir.set_parent_stream_id(5); - headers_ir.set_exclusive(true); - } - headers_ir.SetHeader("foo", "bar"); - SpdySerializedFrame frame(framer.SerializeHeaders(headers_ir)); - uint8_t set_flags = flags; - if (IsHttp2()) { - // TODO(jgraettinger): Add padding to SpdyHeadersIR, - // and implement framing. - set_flags &= ~HEADERS_FLAG_PADDED; - } - SetFrameFlags(&frame, set_flags, spdy_version_); - - if (!IsHttp2() && flags & ~CONTROL_FLAG_FIN) { - EXPECT_CALL(visitor, OnError(_)); - } else if (IsHttp2() && - flags & - ~(CONTROL_FLAG_FIN | HEADERS_FLAG_END_HEADERS | - HEADERS_FLAG_END_SEGMENT | HEADERS_FLAG_PADDED | - HEADERS_FLAG_PRIORITY)) { - EXPECT_CALL(visitor, OnError(_)); - } else { - // Expected callback values - SpdyStreamId stream_id = 57; - bool has_priority = false; - SpdyPriority priority = 0; - SpdyStreamId parent_stream_id = 0; - bool exclusive = false; - bool fin = flags & CONTROL_FLAG_FIN; - bool end = IsSpdy3() || (flags & HEADERS_FLAG_END_HEADERS); - if (IsHttp2() && flags & HEADERS_FLAG_PRIORITY) { - has_priority = true; - priority = 3; - parent_stream_id = 5; - exclusive = true; - } - EXPECT_CALL(visitor, OnHeaders(stream_id, has_priority, priority, - parent_stream_id, exclusive, fin, end)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(57, _, _)) - .WillRepeatedly(testing::Return(true)); - if (flags & DATA_FLAG_FIN && - (IsSpdy3() || flags & HEADERS_FLAG_END_HEADERS)) { - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)); - } else { - // Do not close the stream if we are expecting a CONTINUATION frame. - EXPECT_CALL(visitor, OnStreamFrameData(_, _, 0, true)).Times(0); - } + // Do not close the stream if we are expecting a CONTINUATION frame. + EXPECT_CALL(visitor, OnStreamEnd(_)).Times(0); } framer.ProcessInput(frame.data(), frame.size()); - if (IsSpdy3() && flags & ~CONTROL_FLAG_FIN) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else if (IsHttp2() && flags & ~(CONTROL_FLAG_FIN | - HEADERS_FLAG_END_HEADERS | - HEADERS_FLAG_END_SEGMENT | - HEADERS_FLAG_PADDED | - HEADERS_FLAG_PRIORITY)) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else if (IsHttp2() && ~(flags & HEADERS_FLAG_END_HEADERS)) { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } TEST_P(SpdyFramerTest, PingFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -5076,32 +5112,24 @@ TEST_P(SpdyFramerTest, PingFrameFlags) { SpdySerializedFrame frame(framer.SerializePing(SpdyPingIR(42))); SetFrameFlags(&frame, flags, spdy_version_); - if (IsHttp2() && flags == PING_FLAG_ACK) { + if (IsHttp2() && (flags & PING_FLAG_ACK)) { EXPECT_CALL(visitor, OnPing(42, true)); - } else if (flags == 0) { - EXPECT_CALL(visitor, OnPing(42, false)); } else { - EXPECT_CALL(visitor, OnError(_)); + EXPECT_CALL(visitor, OnPing(42, false)); } framer.ProcessInput(frame.data(), frame.size()); - if ((IsHttp2() && flags == PING_FLAG_ACK) || flags == 0) { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; SpdyFramer framer(spdy_version_); @@ -5111,23 +5139,12 @@ TEST_P(SpdyFramerTest, WindowUpdateFrameFlags) { framer.SerializeWindowUpdate(SpdyWindowUpdateIR(4, 1024))); SetFrameFlags(&frame, flags, spdy_version_); - if (flags != 0) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(visitor, OnWindowUpdate(4, 1024)); - } + EXPECT_CALL(visitor, OnWindowUpdate(4, 1024)); framer.ProcessInput(frame.data(), frame.size()); - if (flags != 0) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } @@ -5136,9 +5153,12 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { return; } + const SpdyStreamId client_id = 123; // Must be odd. + const SpdyStreamId promised_id = 22; // Must be even. uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; testing::StrictMock<test::MockDebugVisitor> debug_visitor; @@ -5146,36 +5166,27 @@ TEST_P(SpdyFramerTest, PushPromiseFrameFlags) { framer.set_visitor(&visitor); framer.set_debug_visitor(&debug_visitor); - EXPECT_CALL(debug_visitor, OnSendCompressedFrame(42, PUSH_PROMISE, _, _)); + EXPECT_CALL(debug_visitor, + OnSendCompressedFrame(client_id, PUSH_PROMISE, _, _)); - SpdyPushPromiseIR push_promise(42, 57); + SpdyPushPromiseIR push_promise(client_id, promised_id); push_promise.SetHeader("foo", "bar"); SpdySerializedFrame frame(framer.SerializePushPromise(push_promise)); // TODO(jgraettinger): Add padding to SpdyPushPromiseIR, // and implement framing. SetFrameFlags(&frame, flags & ~HEADERS_FLAG_PADDED, spdy_version_); - if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, PUSH_PROMISE, _)); - EXPECT_CALL(visitor, OnPushPromise(42, 57, - flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _)) - .WillRepeatedly(testing::Return(true)); - } + bool end = flags & PUSH_PROMISE_FLAG_END_PUSH_PROMISE; + EXPECT_CALL(debug_visitor, + OnReceiveCompressedFrame(client_id, PUSH_PROMISE, _)); + EXPECT_CALL(visitor, OnPushPromise(client_id, promised_id, end)); + EXPECT_CALL(visitor, OnControlFrameHeaderData(client_id, _, _)) + .WillRepeatedly(testing::Return(true)); framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED)) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } @@ -5186,7 +5197,8 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) { uint8_t flags = 0; do { - SCOPED_TRACE(testing::Message() << "Flags " << flags); + SCOPED_TRACE(testing::Message() << "Flags " << flags << std::hex + << static_cast<int>(flags)); testing::StrictMock<test::MockSpdyFramerVisitor> visitor; testing::StrictMock<test::MockDebugVisitor> debug_visitor; @@ -5210,28 +5222,16 @@ TEST_P(SpdyFramerTest, ContinuationFrameFlags) { SpdySerializedFrame frame(framer.SerializeContinuation(continuation)); SetFrameFlags(&frame, flags, spdy_version_); - if (flags & ~(HEADERS_FLAG_END_HEADERS)) { - EXPECT_CALL(visitor, OnError(_)); - } else { - EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, CONTINUATION, _)); - EXPECT_CALL(visitor, OnContinuation(42, - flags & HEADERS_FLAG_END_HEADERS)); - EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _)) - .WillRepeatedly(testing::Return(true)); - } + EXPECT_CALL(debug_visitor, OnReceiveCompressedFrame(42, CONTINUATION, _)); + EXPECT_CALL(visitor, OnContinuation(42, flags & HEADERS_FLAG_END_HEADERS)); + EXPECT_CALL(visitor, OnControlFrameHeaderData(42, _, _)) + .WillRepeatedly(testing::Return(true)); framer.ProcessInput(frame0.data(), frame0.size()); framer.ProcessInput(frame.data(), frame.size()); - if (flags & ~(HEADERS_FLAG_END_HEADERS)) { - EXPECT_EQ(SpdyFramer::SPDY_ERROR, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS, - framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } else { - EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); - EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) - << SpdyFramer::ErrorCodeToString(framer.error_code()); - } + EXPECT_EQ(SpdyFramer::SPDY_READY_FOR_FRAME, framer.state()); + EXPECT_EQ(SpdyFramer::SPDY_NO_ERROR, framer.error_code()) + << SpdyFramer::ErrorCodeToString(framer.error_code()); } while (++flags != 0); } @@ -5449,10 +5449,9 @@ TEST_P(SpdyFramerTest, OnAltSvc) { framer.set_visitor(&visitor); SpdyAltSvcWireFormat::AlternativeService altsvc1( - "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector()); + "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()); SpdyAltSvcWireFormat::AlternativeService altsvc2( - "p\"=i:d", "h_\\o\"st", 123, 42, 0.2, - SpdyAltSvcWireFormat::VersionVector{24}); + "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24}); SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; altsvc_vector.push_back(altsvc1); altsvc_vector.push_back(altsvc2); @@ -5483,10 +5482,9 @@ TEST_P(SpdyFramerTest, OnAltSvcNoOrigin) { framer.set_visitor(&visitor); SpdyAltSvcWireFormat::AlternativeService altsvc1( - "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector()); + "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()); SpdyAltSvcWireFormat::AlternativeService altsvc2( - "p\"=i:d", "h_\\o\"st", 123, 42, 0.2, - SpdyAltSvcWireFormat::VersionVector{24}); + "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24}); SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; altsvc_vector.push_back(altsvc1); altsvc_vector.push_back(altsvc2); @@ -5517,9 +5515,9 @@ TEST_P(SpdyFramerTest, OnAltSvcEmptyProtocolId) { SpdyAltSvcIR altsvc_ir(1); altsvc_ir.set_origin("o1"); altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService( - "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector())); + "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector())); altsvc_ir.add_altsvc(SpdyAltSvcWireFormat::AlternativeService( - "", "h1", 443, 10, 1.0, SpdyAltSvcWireFormat::VersionVector())); + "", "h1", 443, 10, SpdyAltSvcWireFormat::VersionVector())); SpdySerializedFrame frame(framer.SerializeFrame(altsvc_ir)); framer.ProcessInput(frame.data(), frame.size()); @@ -5540,7 +5538,7 @@ TEST_P(SpdyFramerTest, OnAltSvcBadLengths) { framer.set_visitor(&visitor); SpdyAltSvcWireFormat::AlternativeService altsvc( - "pid", "h1", 443, 10, 1.0, SpdyAltSvcWireFormat::VersionVector()); + "pid", "h1", 443, 10, SpdyAltSvcWireFormat::VersionVector()); SpdyAltSvcWireFormat::AlternativeServiceVector altsvc_vector; altsvc_vector.push_back(altsvc); EXPECT_CALL(visitor, OnAltSvc(kStreamId, StringPiece("o1"), altsvc_vector)); @@ -5565,10 +5563,9 @@ TEST_P(SpdyFramerTest, ReadChunkedAltSvcFrame) { SpdyFramer framer(spdy_version_); SpdyAltSvcIR altsvc_ir(1); SpdyAltSvcWireFormat::AlternativeService altsvc1( - "pid1", "host", 443, 5, 1.0, SpdyAltSvcWireFormat::VersionVector()); + "pid1", "host", 443, 5, SpdyAltSvcWireFormat::VersionVector()); SpdyAltSvcWireFormat::AlternativeService altsvc2( - "p\"=i:d", "h_\\o\"st", 123, 42, 0.2, - SpdyAltSvcWireFormat::VersionVector{24}); + "p\"=i:d", "h_\\o\"st", 123, 42, SpdyAltSvcWireFormat::VersionVector{24}); altsvc_ir.add_altsvc(altsvc1); altsvc_ir.add_altsvc(altsvc2); @@ -5679,8 +5676,11 @@ TEST_P(SpdyFramerTest, ReadIncorrectlySizedPing) { // PING frame of size 4, which isn't correct. const unsigned char kFrameData[] = { - 0x00, 0x00, 0x04, 0x06, 0x00, 0x00, 0x00, - 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, + 0x00, 0x00, 0x04, // Length + 0x06, // Type (PING) + 0x00, // Flags + 0x00, 0x00, 0x00, 0x00, // Stream id + 0x00, 0x00, 0x00, 0x01, // Opaque data }; TestSpdyVisitor visitor(spdy_version_); @@ -5736,7 +5736,7 @@ TEST_P(SpdyFramerTest, ReadIncorrectlySizedRstStream) { // to ProcessInput (i.e. will not be calling set_process_single_input_frame()). TEST_P(SpdyFramerTest, ProcessAllInput) { SpdyFramer framer(spdy_version_); - scoped_ptr<TestSpdyVisitor> visitor(new TestSpdyVisitor(spdy_version_)); + std::unique_ptr<TestSpdyVisitor> visitor(new TestSpdyVisitor(spdy_version_)); framer.set_visitor(visitor.get()); // Create two input frames. @@ -5759,8 +5759,8 @@ TEST_P(SpdyFramerTest, ProcessAllInput) { const size_t frame1_size = frame1.size(); const size_t frame2_size = frame2.size(); - LOG(INFO) << "frame1_size = " << frame1_size; - LOG(INFO) << "frame2_size = " << frame2_size; + VLOG(1) << "frame1_size = " << frame1_size; + VLOG(1) << "frame2_size = " << frame2_size; string input_buffer; input_buffer.append(frame1.data(), frame1_size); @@ -5769,7 +5769,7 @@ TEST_P(SpdyFramerTest, ProcessAllInput) { const char* buf = input_buffer.data(); const size_t buf_size = input_buffer.size(); - LOG(INFO) << "buf_size = " << buf_size; + VLOG(1) << "buf_size = " << buf_size; size_t processed = framer.ProcessInput(buf, buf_size); EXPECT_EQ(buf_size, processed); @@ -5786,7 +5786,7 @@ TEST_P(SpdyFramerTest, ProcessAllInput) { TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { SpdyFramer framer(spdy_version_); framer.set_process_single_input_frame(true); - scoped_ptr<TestSpdyVisitor> visitor; + std::unique_ptr<TestSpdyVisitor> visitor; // Create two input frames. const char four_score[] = "Four score and ..."; @@ -5807,8 +5807,8 @@ TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { const size_t frame1_size = frame1.size(); const size_t frame2_size = frame2.size(); - LOG(INFO) << "frame1_size = " << frame1_size; - LOG(INFO) << "frame2_size = " << frame2_size; + VLOG(1) << "frame1_size = " << frame1_size; + VLOG(1) << "frame2_size = " << frame2_size; string input_buffer; input_buffer.append(frame1.data(), frame1_size); @@ -5817,10 +5817,10 @@ TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { const char* buf = input_buffer.data(); const size_t buf_size = input_buffer.size(); - LOG(INFO) << "buf_size = " << buf_size; + VLOG(1) << "buf_size = " << buf_size; for (size_t first_size = 0; first_size <= buf_size; ++first_size) { - LOG(INFO) << "first_size = " << first_size; + VLOG(1) << "first_size = " << first_size; visitor.reset(new TestSpdyVisitor(spdy_version_)); framer.set_visitor(visitor.get()); @@ -5838,7 +5838,7 @@ TEST_P(SpdyFramerTest, ProcessAtMostOneFrame) { const char* rest = buf + processed_first; const size_t remaining = buf_size - processed_first; - LOG(INFO) << "remaining = " << remaining; + VLOG(1) << "remaining = " << remaining; size_t processed_second = framer.ProcessInput(rest, remaining); diff --git a/chromium/net/spdy/spdy_header_block.cc b/chromium/net/spdy/spdy_header_block.cc index b24085fea02..fbcfcdcc376 100644 --- a/chromium/net/spdy/spdy_header_block.cc +++ b/chromium/net/spdy/spdy_header_block.cc @@ -85,7 +85,7 @@ class SpdyHeaderBlock::Storage { private: // TODO(bnc): As soon as move semantics are allowed, change from naked pointer - // to scoped_ptr<>, or better yet, unique_ptr<>. + // to std::unique_ptr<>, or better yet, unique_ptr<>. struct Block { char* data; size_t size = 0; @@ -210,6 +210,11 @@ SpdyHeaderBlock::StringPieceProxy SpdyHeaderBlock::operator[]( return StringPieceProxy(&block_, storage_.get(), iter, out_key); } +StringPiece SpdyHeaderBlock::GetHeader(const StringPiece key) const { + auto iter = block_.find(key); + return iter == block_.end() ? StringPiece() : iter->second; +} + void SpdyHeaderBlock::ReplaceOrAppendHeader(const StringPiece key, const StringPiece value) { // TODO(birenroy): Write new value in place of old value, if it fits. @@ -228,10 +233,10 @@ void SpdyHeaderBlock::AppendHeader(const StringPiece key, block_.insert(make_pair(storage_->Write(key), storage_->Write(value))); } -scoped_ptr<base::Value> SpdyHeaderBlockNetLogCallback( +std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback( const SpdyHeaderBlock* headers, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); base::DictionaryValue* headers_dict = new base::DictionaryValue(); for (SpdyHeaderBlock::const_iterator it = headers->begin(); it != headers->end(); ++it) { diff --git a/chromium/net/spdy/spdy_header_block.h b/chromium/net/spdy/spdy_header_block.h index 58d6cf4cdd8..43b4ea13a7e 100644 --- a/chromium/net/spdy/spdy_header_block.h +++ b/chromium/net/spdy/spdy_header_block.h @@ -11,7 +11,6 @@ #include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "net/base/linked_hash_map.h" #include "net/base/net_export.h" @@ -83,6 +82,11 @@ class NET_EXPORT SpdyHeaderBlock { // Allows either lookup or mutation of the value associated with a key. StringPieceProxy operator[](const base::StringPiece key); + // Non-mutating lookup of header value. Returns empty StringPiece if key not + // present. To distinguish between absence of header and empty header value, + // use find(). + base::StringPiece GetHeader(const base::StringPiece key) const; + // This object provides automatic conversions that allow SpdyHeaderBlock to be // nearly a drop-in replacement for linked_hash_map<string, string>. It reads // data from or writes data to a SpdyHeaderBlock::Storage. @@ -126,11 +130,11 @@ class NET_EXPORT SpdyHeaderBlock { void AppendHeader(const base::StringPiece key, const base::StringPiece value); MapType block_; - scoped_ptr<Storage> storage_; + std::unique_ptr<Storage> storage_; }; // Converts a SpdyHeaderBlock into NetLog event parameters. -NET_EXPORT scoped_ptr<base::Value> SpdyHeaderBlockNetLogCallback( +NET_EXPORT std::unique_ptr<base::Value> SpdyHeaderBlockNetLogCallback( const SpdyHeaderBlock* headers, NetLogCaptureMode capture_mode); diff --git a/chromium/net/spdy/spdy_header_block_test.cc b/chromium/net/spdy/spdy_header_block_test.cc index ec2b665106c..a263f2a136d 100644 --- a/chromium/net/spdy/spdy_header_block_test.cc +++ b/chromium/net/spdy/spdy_header_block_test.cc @@ -4,9 +4,9 @@ #include "net/spdy/spdy_header_block.h" +#include <memory> #include <utility> -#include "base/memory/scoped_ptr.h" #include "base/values.h" #include "net/log/net_log.h" #include "net/spdy/spdy_test_utils.h" @@ -30,6 +30,7 @@ TEST(SpdyHeaderBlockTest, EmptyBlock) { EXPECT_TRUE(block.empty()); EXPECT_EQ(0u, block.size()); EXPECT_EQ(block.end(), block.find("foo")); + EXPECT_EQ("", block.GetHeader("foo")); EXPECT_TRUE(block.end() == block.begin()); // Should have no effect. @@ -47,12 +48,15 @@ TEST(SpdyHeaderBlockTest, AddHeaders) { EXPECT_EQ(Pair("foo", string(300, 'x')), *block1.find("foo")); EXPECT_EQ("baz", block1["bar"]); + EXPECT_EQ("baz", block1.GetHeader("bar")); string qux("qux"); EXPECT_EQ("qux2", block1[qux]); + EXPECT_EQ("qux2", block1.GetHeader(qux)); EXPECT_EQ(Pair("key", "value"), *block1.find("key")); block1.erase("key"); EXPECT_EQ(block1.end(), block1.find("key")); + EXPECT_EQ("", block1.GetHeader("key")); } // This test verifies that SpdyHeaderBlock can be copied. @@ -76,7 +80,7 @@ TEST(SpdyHeaderBlockTest, ToNetLogParamAndBackAgain) { headers["A"] = "a"; headers["B"] = "b"; - scoped_ptr<base::Value> event_param(SpdyHeaderBlockNetLogCallback( + std::unique_ptr<base::Value> event_param(SpdyHeaderBlockNetLogCallback( &headers, NetLogCaptureMode::IncludeCookiesAndCredentials())); SpdyHeaderBlock headers2; diff --git a/chromium/net/spdy/spdy_headers_block_parser.cc b/chromium/net/spdy/spdy_headers_block_parser.cc index 83a216028d8..d5f03413a18 100644 --- a/chromium/net/spdy/spdy_headers_block_parser.cc +++ b/chromium/net/spdy/spdy_headers_block_parser.cc @@ -5,6 +5,7 @@ #include "net/spdy/spdy_headers_block_parser.h" #include "base/sys_byteorder.h" +#include "net/spdy/spdy_bug_tracker.h" namespace net { namespace { @@ -45,7 +46,7 @@ bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( error_ = NO_PARSER_ERROR; } if (error_ != NO_PARSER_ERROR) { - LOG(DFATAL) << "Unexpected error: " << error_; + SPDY_BUG << "Unexpected error: " << error_; return false; } @@ -55,13 +56,13 @@ bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( stream_id_ = stream_id; } if (stream_id != stream_id_) { - LOG(DFATAL) << "Unexpected stream id: " << stream_id << " (expected " - << stream_id_ << ")"; + SPDY_BUG << "Unexpected stream id: " << stream_id << " (expected " + << stream_id_ << ")"; error_ = UNEXPECTED_STREAM_ID; return false; } if (stream_id_ == kInvalidStreamId) { - LOG(DFATAL) << "Expected nonzero stream id, saw: " << stream_id_; + SPDY_BUG << "Expected nonzero stream id, saw: " << stream_id_; error_ = UNEXPECTED_STREAM_ID; return false; } diff --git a/chromium/net/spdy/spdy_headers_block_parser.h b/chromium/net/spdy/spdy_headers_block_parser.h index 4ee8760dc7d..8e2db8b4ca4 100644 --- a/chromium/net/spdy/spdy_headers_block_parser.h +++ b/chromium/net/spdy/spdy_headers_block_parser.h @@ -8,8 +8,9 @@ #include <stddef.h> #include <stdint.h> +#include <memory> + #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "net/base/net_export.h" #include "net/spdy/spdy_headers_handler_interface.h" diff --git a/chromium/net/spdy/spdy_headers_block_parser_test.cc b/chromium/net/spdy/spdy_headers_block_parser_test.cc index 85beb6cd7b4..2f80fdc3f81 100644 --- a/chromium/net/spdy/spdy_headers_block_parser_test.cc +++ b/chromium/net/spdy/spdy_headers_block_parser_test.cc @@ -4,11 +4,12 @@ #include "net/spdy/spdy_headers_block_parser.h" +#include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/sys_byteorder.h" +#include "net/spdy/spdy_test_utils.h" #include "net/test/gtest_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -86,7 +87,7 @@ class SpdyHeadersBlockParserTest : SpdyMajorVersion spdy_version_; MockSpdyHeadersHandler handler_; - scoped_ptr<SpdyHeadersBlockParser> parser_; + std::unique_ptr<SpdyHeadersBlockParser> parser_; static const char *const kBaseKey; static const char *const kBaseValue; @@ -247,7 +248,7 @@ TEST_P(SpdyHeadersBlockParserTest, WrongStreamIdTest) { EXPECT_FALSE(parser_->HandleControlFrameHeadersData(1, headers.data(), 1)); EXPECT_EQ(SpdyHeadersBlockParser::NEED_MORE_DATA, parser_->get_error()); bool result; - EXPECT_DFATAL( + EXPECT_SPDY_BUG( result = parser_->HandleControlFrameHeadersData(2, headers.data() + 1, 1), "Unexpected stream id: 2 \\(expected 1\\)"); EXPECT_FALSE(result); @@ -257,7 +258,7 @@ TEST_P(SpdyHeadersBlockParserTest, WrongStreamIdTest) { TEST_P(SpdyHeadersBlockParserTest, InvalidStreamIdTest) { string headers(CreateHeaders(kNumHeadersInBlock, false)); bool result; - EXPECT_DFATAL( + EXPECT_SPDY_BUG( result = parser_->HandleControlFrameHeadersData(0, headers.data(), 1), "Expected nonzero stream id, saw: 0"); EXPECT_FALSE(result); diff --git a/chromium/net/spdy/spdy_headers_handler_interface.h b/chromium/net/spdy/spdy_headers_handler_interface.h index a6861afa217..99944c67afb 100644 --- a/chromium/net/spdy/spdy_headers_handler_interface.h +++ b/chromium/net/spdy/spdy_headers_handler_interface.h @@ -8,12 +8,13 @@ #include <stddef.h> #include "base/strings/string_piece.h" +#include "net/base/net_export.h" namespace net { // This interface defines how an object that accepts header data should behave. // It is used by both SpdyHeadersBlockParser and HpackDecoder. -class SpdyHeadersHandlerInterface { +class NET_EXPORT_PRIVATE SpdyHeadersHandlerInterface { public: virtual ~SpdyHeadersHandlerInterface() {} diff --git a/chromium/net/spdy/spdy_http_stream.cc b/chromium/net/spdy/spdy_http_stream.cc index 4fdbc0e918e..259581a5229 100644 --- a/chromium/net/spdy/spdy_http_stream.cc +++ b/chromium/net/spdy/spdy_http_stream.cc @@ -14,7 +14,7 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "net/base/host_port_pair.h" #include "net/base/upload_data_stream.h" @@ -29,6 +29,8 @@ namespace net { +const size_t SpdyHttpStream::kRequestBodyBufferSize = 1 << 14; // 16KB + SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, bool direct) : spdy_session_(spdy_session), @@ -232,9 +234,7 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, CHECK(!request_body_buf_.get()); if (HasUploadData()) { - // Use kMaxSpdyFrameChunkSize as the buffer size, since the request - // body data is written with this size at a time. - request_body_buf_ = new IOBufferWithSize(kMaxSpdyFrameChunkSize); + request_body_buf_ = new IOBufferWithSize(kRequestBodyBufferSize); // The request body buffer is empty at first. request_body_buf_size_ = 0; } @@ -274,7 +274,7 @@ int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers, return ERR_IO_PENDING; } - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); + std::unique_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock); CreateSpdyHeadersFromHttpRequest(*request_info_, request_headers, stream_->GetProtocolVersion(), direct_, headers.get()); @@ -351,7 +351,7 @@ SpdyResponseHeadersStatus SpdyHttpStream::OnResponseHeadersUpdated( return RESPONSE_HEADERS_ARE_COMPLETE; } -void SpdyHttpStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +void SpdyHttpStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { CHECK_EQ(response_headers_status_, RESPONSE_HEADERS_ARE_COMPLETE); // Note that data may be received for a SpdyStream prior to the user calling diff --git a/chromium/net/spdy/spdy_http_stream.h b/chromium/net/spdy/spdy_http_stream.h index 76130d8c641..25d60e352fc 100644 --- a/chromium/net/spdy/spdy_http_stream.h +++ b/chromium/net/spdy/spdy_http_stream.h @@ -32,6 +32,7 @@ class UploadDataStream; class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, public HttpStream { public: + static const size_t kRequestBodyBufferSize; // |spdy_session| must not be NULL. SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session, bool direct); ~SpdyHttpStream() override; @@ -89,7 +90,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, void OnRequestHeadersSent() override; SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) override; - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; void OnDataSent() override; void OnTrailers(const SpdyHeaderBlock& trailers) override; void OnClose(int status) override; @@ -147,7 +148,7 @@ class NET_EXPORT_PRIVATE SpdyHttpStream : public SpdyStream::Delegate, // It is not owned by this stream object, or point to |push_response_info_|. HttpResponseInfo* response_info_; - scoped_ptr<HttpResponseInfo> push_response_info_; + std::unique_ptr<HttpResponseInfo> push_response_info_; // We don't use SpdyStream's |response_header_status_| as we // sometimes call back into our delegate before it is updated. diff --git a/chromium/net/spdy/spdy_http_stream_unittest.cc b/chromium/net/spdy/spdy_http_stream_unittest.cc index 9ef70cede19..a6d4a12abb1 100644 --- a/chromium/net/spdy/spdy_http_stream_unittest.cc +++ b/chromium/net/spdy/spdy_http_stream_unittest.cc @@ -6,7 +6,8 @@ #include <stdint.h> -#include "base/memory/scoped_ptr.h" +#include <memory> + #include "base/message_loop/message_loop.h" #include "base/run_loop.h" #include "base/stl_util.h" @@ -126,8 +127,8 @@ class SpdyHttpStreamTest : public testing::Test, SpdyTestUtil spdy_util_; TestNetLog net_log_; SpdySessionDependencies session_deps_; - scoped_ptr<SequencedSocketData> sequenced_data_; - scoped_ptr<HttpNetworkSession> http_session_; + std::unique_ptr<SequencedSocketData> sequenced_data_; + std::unique_ptr<HttpNetworkSession> http_session_; base::WeakPtr<SpdySession> session_; private: @@ -162,12 +163,12 @@ TEST_P(SpdyHttpStreamTest, GetUploadProgressBeforeInitialization) { } TEST_P(SpdyHttpStreamTest, SendRequest) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2) // EOF @@ -185,7 +186,8 @@ TEST_P(SpdyHttpStreamTest, SendRequest) { HttpResponseInfo response; HttpRequestHeaders headers; BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); // Make sure getting load timing information the stream early does not crash. LoadTimingInfo load_timing_info; EXPECT_FALSE(http_stream->GetLoadTimingInfo(&load_timing_info)); @@ -223,21 +225,21 @@ TEST_P(SpdyHttpStreamTest, SendRequest) { } TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, "", 0, true)); MockRead reads[] = { CreateMockRead(*resp1, 2), @@ -258,7 +260,8 @@ TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { TestCompletionCallback callback1; HttpResponseInfo response1; HttpRequestHeaders headers1; - scoped_ptr<SpdyHttpStream> http_stream1(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream1( + new SpdyHttpStream(session_, true)); HttpRequestInfo request2; request2.method = "GET"; @@ -266,7 +269,8 @@ TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { TestCompletionCallback callback2; HttpResponseInfo response2; HttpRequestHeaders headers2; - scoped_ptr<SpdyHttpStream> http_stream2(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream2( + new SpdyHttpStream(session_, true)); // First write. ASSERT_EQ(OK, @@ -325,16 +329,16 @@ TEST_P(SpdyHttpStreamTest, LoadTimingTwoRequests) { TEST_P(SpdyHttpStreamTest, SendChunkedPost) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_FIN)); MockWrite writes[] = { CreateMockWrite(*req, 0), // request CreateMockWrite(*body, 1) // POST upload frame }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -390,16 +394,16 @@ TEST_P(SpdyHttpStreamTest, SendChunkedPost) { TEST_P(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( framer.CreateDataFrame(1, kUploadData, kUploadDataSize, DATA_FLAG_NONE)); MockWrite writes[] = { CreateMockWrite(*req, 0), // Request CreateMockWrite(*body, 1) // First POST upload frame }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { MockRead(ASYNC, ERR_CONNECTION_CLOSED, 2) // Server hangs up early. @@ -461,13 +465,13 @@ TEST_P(SpdyHttpStreamTest, ConnectionClosedDuringChunkedPost) { TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { const char kUploadData1[] = "12345678"; const int kUploadData1Size = arraysize(kUploadData1)-1; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> chunk1( + std::unique_ptr<SpdySerializedFrame> chunk1( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> chunk2(spdy_util_.ConstructSpdyBodyFrame( 1, kUploadData1, kUploadData1Size, false)); - scoped_ptr<SpdySerializedFrame> chunk3( + std::unique_ptr<SpdySerializedFrame> chunk3( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), @@ -475,7 +479,7 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { CreateMockWrite(*chunk2, 2), CreateMockWrite(*chunk3, 3), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 4), @@ -501,7 +505,8 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { upload_stream.AppendData(kUploadData, kUploadDataSize, false); BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log, CompletionCallback())); @@ -564,18 +569,18 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPost) { // Test that the SpdyStream state machine can handle sending a final empty data // frame when uploading a chunked data stream. TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> chunk1( + std::unique_ptr<SpdySerializedFrame> chunk1( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> chunk2( + std::unique_ptr<SpdySerializedFrame> chunk2( spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), CreateMockWrite(*chunk1, 1), // POST upload frames CreateMockWrite(*chunk2, 2), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 3), @@ -600,7 +605,8 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { upload_stream.AppendData(kUploadData, kUploadDataSize, false); BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log, CompletionCallback())); @@ -656,15 +662,15 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithEmptyFinalDataFrame) { // Test that the SpdyStream state machine handles a chunked upload with no // payload. Unclear if this is a case worth supporting. TEST_P(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> chunk( + std::unique_ptr<SpdySerializedFrame> chunk( spdy_util_.ConstructSpdyBodyFrame(1, "", 0, true)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), CreateMockWrite(*chunk, 1), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -688,7 +694,8 @@ TEST_P(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { upload_stream.AppendData("", 0, true); BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log, CompletionCallback())); @@ -728,12 +735,12 @@ TEST_P(SpdyHttpStreamTest, ChunkedPostWithEmptyPayload) { TEST_P(SpdyHttpStreamTest, SpdyURLTest) { const char* const full_url = "http://www.example.org/foo?query=what#anchor"; const char* const base_url = "http://www.example.org/foo?query=what"; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(base_url, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2) // EOF @@ -751,7 +758,8 @@ TEST_P(SpdyHttpStreamTest, SpdyURLTest) { HttpResponseInfo response; HttpRequestHeaders headers; BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); ASSERT_EQ(OK, http_stream->InitializeStream( &request, DEFAULT_PRIORITY, net_log, CompletionCallback())); @@ -776,17 +784,17 @@ TEST_P(SpdyHttpStreamTest, SpdyURLTest) { // Test the receipt of a WINDOW_UPDATE frame while waiting for a chunk to be // made available is handled correctly. TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> chunk1( + std::unique_ptr<SpdySerializedFrame> chunk1( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0), CreateMockWrite(*chunk1, 1), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); MockRead reads[] = { CreateMockRead(*window_update, 2), @@ -812,7 +820,8 @@ TEST_P(SpdyHttpStreamTest, DelayedSendChunkedPostWithWindowUpdate) { ASSERT_EQ(OK, upload_stream.Init(TestCompletionCallback().callback())); BoundNetLog net_log; - scoped_ptr<SpdyHttpStream> http_stream(new SpdyHttpStream(session_, true)); + std::unique_ptr<SpdyHttpStream> http_stream( + new SpdyHttpStream(session_, true)); ASSERT_EQ(OK, http_stream->InitializeStream(&request, DEFAULT_PRIORITY, net_log, CompletionCallback())); diff --git a/chromium/net/spdy/spdy_network_transaction_unittest.cc b/chromium/net/spdy/spdy_network_transaction_unittest.cc index 900f1038a45..d1ed0689a22 100644 --- a/chromium/net/spdy/spdy_network_transaction_unittest.cc +++ b/chromium/net/spdy/spdy_network_transaction_unittest.cc @@ -2,6 +2,8 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include <cmath> +#include <memory> #include <string> #include <utility> #include <vector> @@ -10,11 +12,11 @@ #include "base/bind_helpers.h" #include "base/files/file_util.h" #include "base/files/scoped_temp_dir.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" #include "base/test/test_file_util.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "net/base/auth.h" #include "net/base/chunked_upload_data_stream.h" #include "net/base/elements_upload_data_stream.h" @@ -57,6 +59,8 @@ namespace { using testing::Each; using testing::Eq; +const int32_t kBufferSize = SpdyHttpStream::kRequestBodyBufferSize; + enum SpdyNetworkTransactionTestSSLType { // Request an https:// URL and use NPN (or ALPN) to negotiate SPDY during // the TLS handshake. @@ -109,7 +113,7 @@ void UpdateSpdySessionDependencies(SpdyNetworkTransactionTestParams test_params, if (test_params.ssl_type == HTTP_SPDY_VIA_ALT_SVC) { base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); session_deps->http_server_properties.SetAlternativeService( - HostPortPair("www.example.org", 80), + url::SchemeHostPort("http", "www.example.org", 80), AlternativeService(AlternateProtocolFromNextProto(test_params.protocol), "www.example.org", 443), expiration); @@ -118,19 +122,20 @@ void UpdateSpdySessionDependencies(SpdyNetworkTransactionTestParams test_params, test_params.priority_to_dependency; } -scoped_ptr<SpdySessionDependencies> CreateSpdySessionDependencies( +std::unique_ptr<SpdySessionDependencies> CreateSpdySessionDependencies( SpdyNetworkTransactionTestParams test_params) { - scoped_ptr<SpdySessionDependencies> session_deps( + std::unique_ptr<SpdySessionDependencies> session_deps( new SpdySessionDependencies(test_params.protocol)); UpdateSpdySessionDependencies(test_params, session_deps.get()); return session_deps; } -scoped_ptr<SpdySessionDependencies> CreateSpdySessionDependencies( +std::unique_ptr<SpdySessionDependencies> CreateSpdySessionDependencies( SpdyNetworkTransactionTestParams test_params, - scoped_ptr<ProxyService> proxy_service) { - scoped_ptr<SpdySessionDependencies> session_deps(new SpdySessionDependencies( - test_params.protocol, std::move(proxy_service))); + std::unique_ptr<ProxyService> proxy_service) { + std::unique_ptr<SpdySessionDependencies> session_deps( + new SpdySessionDependencies(test_params.protocol, + std::move(proxy_service))); UpdateSpdySessionDependencies(test_params, session_deps.get()); return session_deps; } @@ -174,7 +179,7 @@ class SpdyNetworkTransactionTest RequestPriority priority, const BoundNetLog& log, SpdyNetworkTransactionTestParams test_params, - scoped_ptr<SpdySessionDependencies> session_deps) + std::unique_ptr<SpdySessionDependencies> session_deps) : request_(request), priority_(priority), session_deps_(session_deps.get() == NULL @@ -307,7 +312,7 @@ class SpdyNetworkTransactionTest void RunToCompletionWithSSLData( SocketDataProvider* data, - scoped_ptr<SSLSocketDataProvider> ssl_provider) { + std::unique_ptr<SSLSocketDataProvider> ssl_provider) { RunPreTestSetup(); AddDataWithSSLSocketDataProvider(data, std::move(ssl_provider)); RunDefaultTest(); @@ -315,7 +320,7 @@ class SpdyNetworkTransactionTest } void AddData(SocketDataProvider* data) { - scoped_ptr<SSLSocketDataProvider> ssl_provider( + std::unique_ptr<SSLSocketDataProvider> ssl_provider( new SSLSocketDataProvider(ASYNC, OK)); ssl_provider->cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); @@ -324,7 +329,7 @@ class SpdyNetworkTransactionTest void AddDataWithSSLSocketDataProvider( SocketDataProvider* data, - scoped_ptr<SSLSocketDataProvider> ssl_provider) { + std::unique_ptr<SSLSocketDataProvider> ssl_provider) { data_vector_.push_back(data); if (ssl_provider->next_proto_status == SSLClientSocket::kNextProtoUnsupported) { @@ -338,8 +343,8 @@ class SpdyNetworkTransactionTest session_deps_->socket_factory->AddSocketDataProvider(data); if (test_params_.ssl_type == HTTP_SPDY_VIA_ALT_SVC) { MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING); - scoped_ptr<StaticSocketDataProvider> hanging_non_alt_svc_socket( - make_scoped_ptr(new StaticSocketDataProvider(NULL, 0, NULL, 0))); + std::unique_ptr<StaticSocketDataProvider> hanging_non_alt_svc_socket( + base::WrapUnique(new StaticSocketDataProvider(NULL, 0, NULL, 0))); hanging_non_alt_svc_socket->set_connect_data(hanging_connect); session_deps_->socket_factory->AddSocketDataProvider( hanging_non_alt_svc_socket.get()); @@ -347,7 +352,7 @@ class SpdyNetworkTransactionTest } } - void SetSession(scoped_ptr<HttpNetworkSession> session) { + void SetSession(std::unique_ptr<HttpNetworkSession> session) { session_ = std::move(session); } HttpNetworkTransaction* trans() { return trans_.get(); } @@ -355,7 +360,7 @@ class SpdyNetworkTransactionTest TransactionHelperResult& output() { return output_; } const HttpRequestInfo& request() const { return request_; } HttpNetworkSession* session() const { return session_.get(); } - scoped_ptr<SpdySessionDependencies>& session_deps() { + std::unique_ptr<SpdySessionDependencies>& session_deps() { return session_deps_; } int port() const { return port_; } @@ -365,18 +370,18 @@ class SpdyNetworkTransactionTest private: typedef std::vector<SocketDataProvider*> DataVector; - typedef std::vector<scoped_ptr<SSLSocketDataProvider>> SSLVector; - typedef std::vector<scoped_ptr<SocketDataProvider>> AlternateVector; + typedef std::vector<std::unique_ptr<SSLSocketDataProvider>> SSLVector; + typedef std::vector<std::unique_ptr<SocketDataProvider>> AlternateVector; HttpRequestInfo request_; RequestPriority priority_; - scoped_ptr<SpdySessionDependencies> session_deps_; - scoped_ptr<HttpNetworkSession> session_; + std::unique_ptr<SpdySessionDependencies> session_deps_; + std::unique_ptr<HttpNetworkSession> session_; TransactionHelperResult output_; - scoped_ptr<SocketDataProvider> first_transaction_; + std::unique_ptr<SocketDataProvider> first_transaction_; SSLVector ssl_vector_; TestCompletionCallback callback_; - scoped_ptr<HttpNetworkTransaction> trans_; - scoped_ptr<HttpNetworkTransaction> trans_http_; + std::unique_ptr<HttpNetworkTransaction> trans_; + std::unique_ptr<HttpNetworkTransaction> trans_http_; DataVector data_vector_; AlternateVector alternate_vector_; const BoundNetLog log_; @@ -420,8 +425,8 @@ class SpdyNetworkTransactionTest const HttpRequestInfo& CreatePostRequest() { if (!post_request_initialized_) { - std::vector<scoped_ptr<UploadElementReader>> element_readers; - element_readers.push_back(make_scoped_ptr( + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + element_readers.push_back(base::WrapUnique( new UploadBytesElementReader(kUploadData, kUploadDataSize))); upload_data_stream_.reset( new ElementsUploadDataStream(std::move(element_readers), 0)); @@ -441,8 +446,8 @@ class SpdyNetworkTransactionTest CHECK_EQ(static_cast<int>(kUploadDataSize), base::WriteFile(file_path, kUploadData, kUploadDataSize)); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - element_readers.push_back(make_scoped_ptr(new UploadFileElementReader( + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + element_readers.push_back(base::WrapUnique(new UploadFileElementReader( base::ThreadTaskRunnerHandle::Get().get(), file_path, 0, kUploadDataSize, base::Time()))); upload_data_stream_.reset( @@ -466,8 +471,8 @@ class SpdyNetworkTransactionTest base::WriteFile(file_path, kUploadData, kUploadDataSize)); CHECK(base::MakeFileUnreadable(file_path)); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - element_readers.push_back(make_scoped_ptr(new UploadFileElementReader( + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + element_readers.push_back(base::WrapUnique(new UploadFileElementReader( base::ThreadTaskRunnerHandle::Get().get(), file_path, 0, kUploadDataSize, base::Time()))); upload_data_stream_.reset( @@ -491,13 +496,13 @@ class SpdyNetworkTransactionTest CHECK_EQ(static_cast<int>(kUploadDataSize), base::WriteFile(file_path, kUploadData, kUploadDataSize)); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - element_readers.push_back(make_scoped_ptr( + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + element_readers.push_back(base::WrapUnique( new UploadBytesElementReader(kUploadData, kFileRangeOffset))); - element_readers.push_back(make_scoped_ptr(new UploadFileElementReader( + element_readers.push_back(base::WrapUnique(new UploadFileElementReader( base::ThreadTaskRunnerHandle::Get().get(), file_path, kFileRangeOffset, kFileRangeLength, base::Time()))); - element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader( + element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( kUploadData + kFileRangeOffset + kFileRangeLength, kUploadDataSize - (kFileRangeOffset + kFileRangeLength)))); upload_data_stream_.reset( @@ -583,7 +588,7 @@ class SpdyNetworkTransactionTest rv = callback.WaitForResult(); // Request the pushed path. - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); rv = trans2->Start( &CreateGetPushRequest(), callback.callback(), BoundNetLog()); @@ -604,6 +609,16 @@ class SpdyNetworkTransactionTest EXPECT_TRUE(data->AllReadDataConsumed()); EXPECT_TRUE(data->AllWriteDataConsumed()); + LoadTimingInfo load_timing_info; + EXPECT_TRUE(trans->GetLoadTimingInfo(&load_timing_info)); + EXPECT_TRUE(load_timing_info.push_start.is_null()); + EXPECT_TRUE(load_timing_info.push_end.is_null()); + + LoadTimingInfo load_timing_info2; + EXPECT_TRUE(trans2->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_FALSE(load_timing_info2.push_start.is_null()); + EXPECT_FALSE(load_timing_info2.push_end.is_null()); + // Verify that the received push data is same as the expected push data. EXPECT_EQ(result2.compare(expected), 0) << "Received data: " << result2 @@ -626,7 +641,7 @@ class SpdyNetworkTransactionTest static void StartTransactionCallback(HttpNetworkSession* session, GURL url, int result) { - scoped_ptr<HttpNetworkTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session)); TestCompletionCallback callback; HttpRequestInfo request; @@ -661,8 +676,8 @@ class SpdyNetworkTransactionTest SpdyTestUtil spdy_util_; private: - scoped_ptr<ChunkedUploadDataStream> upload_chunked_data_stream_; - scoped_ptr<UploadDataStream> upload_data_stream_; + std::unique_ptr<ChunkedUploadDataStream> upload_chunked_data_stream_; + std::unique_ptr<UploadDataStream> upload_data_stream_; bool get_request_initialized_; bool post_request_initialized_; bool chunked_post_request_initialized_; @@ -702,23 +717,23 @@ INSTANTIATE_TEST_CASE_P( // Verify HttpNetworkTransaction constructor. TEST_P(SpdyNetworkTransactionTest, Constructor) { - scoped_ptr<SpdySessionDependencies> session_deps( + std::unique_ptr<SpdySessionDependencies> session_deps( CreateSpdySessionDependencies(GetParam())); - scoped_ptr<HttpNetworkSession> session( + std::unique_ptr<HttpNetworkSession> session( SpdySessionDependencies::SpdyCreateSession(session_deps.get())); - scoped_ptr<HttpTransaction> trans( + std::unique_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); } TEST_P(SpdyNetworkTransactionTest, Get) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -744,7 +759,7 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { spdy_test_util.set_default_url(GURL(GetDefaultUrl())); // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, p, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; @@ -774,9 +789,9 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { FAIL(); } - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_test_util.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_test_util.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -809,31 +824,31 @@ TEST_P(SpdyNetworkTransactionTest, GetAtEachPriority) { // can allow multiple streams in flight. TEST_P(SpdyNetworkTransactionTest, ThreeGets) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp3( + std::unique_ptr<SpdySerializedFrame> resp3( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); - scoped_ptr<SpdySerializedFrame> body3( + std::unique_ptr<SpdySerializedFrame> body3( spdy_util_.ConstructSpdyBodyFrame(5, false)); - scoped_ptr<SpdySerializedFrame> fbody3( + std::unique_ptr<SpdySerializedFrame> fbody3( spdy_util_.ConstructSpdyBodyFrame(5, true)); MockWrite writes[] = { @@ -870,11 +885,11 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) { // on will negotiate SPDY and will be used for all requests. helper.AddData(&data_placeholder1); helper.AddData(&data_placeholder2); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans3( + std::unique_ptr<HttpNetworkTransaction> trans3( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback1; @@ -915,22 +930,22 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGets) { } TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); MockWrite writes[] = { @@ -961,9 +976,9 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { // the same time which results in two sockets being connected. The first // on will negotiate SPDY and will be used for all requests. helper.AddData(&data_placeholder); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback1; @@ -1006,22 +1021,22 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBinding) { } TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); MockWrite writes[] = { @@ -1055,9 +1070,9 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { helper.AddData(&data_placeholder); helper.AddData(&data_placeholder); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback1; @@ -1066,15 +1081,10 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { HttpRequestInfo httpreq = CreateGetRequest(); // Preconnect the first. - SSLConfig preconnect_ssl_config; - helper.session()->ssl_config_service()->GetSSLConfig(&preconnect_ssl_config); HttpStreamFactory* http_stream_factory = helper.session()->http_stream_factory(); - helper.session()->GetAlpnProtos(&preconnect_ssl_config.alpn_protos); - helper.session()->GetNpnProtos(&preconnect_ssl_config.npn_protos); - http_stream_factory->PreconnectStreams(1, httpreq, preconnect_ssl_config, - preconnect_ssl_config); + http_stream_factory->PreconnectStreams(1, httpreq); out.rv = trans1->Start(&httpreq, callback1.callback(), log); ASSERT_EQ(ERR_IO_PENDING, out.rv); @@ -1117,42 +1127,42 @@ TEST_P(SpdyNetworkTransactionTest, TwoGetsLateBindingFromPreconnect) { TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // Construct the request. // Each request fully completes before the next starts. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); spdy_util_.UpdateWithStreamDestruction(3); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp3( + std::unique_ptr<SpdySerializedFrame> resp3( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); - scoped_ptr<SpdySerializedFrame> body3( + std::unique_ptr<SpdySerializedFrame> body3( spdy_util_.ConstructSpdyBodyFrame(5, false)); - scoped_ptr<SpdySerializedFrame> fbody3( + std::unique_ptr<SpdySerializedFrame> fbody3( spdy_util_.ConstructSpdyBodyFrame(5, true)); SettingsMap settings; const uint32_t max_concurrent_streams = 1; settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); MockWrite writes[] = { @@ -1186,11 +1196,11 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { BoundNetLog(), GetParam(), NULL); helper.RunPreTestSetup(); helper.AddData(&data); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans3( + std::unique_ptr<HttpNetworkTransaction> trans3( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback1; @@ -1257,50 +1267,50 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrent) { // the response from the server. TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); spdy_util_.UpdateWithStreamDestruction(3); - scoped_ptr<SpdySerializedFrame> req4( + std::unique_ptr<SpdySerializedFrame> req4( spdy_util_.ConstructSpdyGet(nullptr, 0, 5, HIGHEST, true)); - scoped_ptr<SpdySerializedFrame> resp4( + std::unique_ptr<SpdySerializedFrame> resp4( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); - scoped_ptr<SpdySerializedFrame> fbody4( + std::unique_ptr<SpdySerializedFrame> fbody4( spdy_util_.ConstructSpdyBodyFrame(5, true)); spdy_util_.UpdateWithStreamDestruction(5); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 7, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp3( + std::unique_ptr<SpdySerializedFrame> resp3( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 7)); - scoped_ptr<SpdySerializedFrame> body3( + std::unique_ptr<SpdySerializedFrame> body3( spdy_util_.ConstructSpdyBodyFrame(7, false)); - scoped_ptr<SpdySerializedFrame> fbody3( + std::unique_ptr<SpdySerializedFrame> fbody3( spdy_util_.ConstructSpdyBodyFrame(7, true)); SettingsMap settings; const uint32_t max_concurrent_streams = 1; settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -1336,13 +1346,13 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { helper.RunPreTestSetup(); helper.AddData(&data); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans3( + std::unique_ptr<HttpNetworkTransaction> trans3( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans4( + std::unique_ptr<HttpNetworkTransaction> trans4( new HttpNetworkTransaction(HIGHEST, helper.session())); TestCompletionCallback callback1; @@ -1421,32 +1431,32 @@ TEST_P(SpdyNetworkTransactionTest, FourGetsWithMaxConcurrentPriority) { // the spdy_session TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fbody( + std::unique_ptr<SpdySerializedFrame> fbody( spdy_util_.ConstructSpdyBodyFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, false)); - scoped_ptr<SpdySerializedFrame> fbody2( + std::unique_ptr<SpdySerializedFrame> fbody2( spdy_util_.ConstructSpdyBodyFrame(3, true)); SettingsMap settings; const uint32_t max_concurrent_streams = 1; settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); MockWrite writes[] = { @@ -1473,11 +1483,11 @@ TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentDelete) { BoundNetLog(), GetParam(), NULL); helper.RunPreTestSetup(); helper.AddData(&data); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); - scoped_ptr<HttpNetworkTransaction> trans3( + std::unique_ptr<HttpNetworkTransaction> trans3( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback1; @@ -1560,28 +1570,28 @@ class KillerCallback : public TestCompletionCallbackBase { // a pending stream creation. http://crbug.com/52901 TEST_P(SpdyNetworkTransactionTest, ThreeGetsWithMaxConcurrentSocketClose) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> fin_body( + std::unique_ptr<SpdySerializedFrame> fin_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); SettingsMap settings; const uint32_t max_concurrent_streams = 1; settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); MockWrite writes[] = { @@ -1663,17 +1673,17 @@ TEST_P(SpdyNetworkTransactionTest, Put) { request.method = "PUT"; request.url = GURL(GetDefaultUrl()); - scoped_ptr<SpdyHeaderBlock> put_headers( + std::unique_ptr<SpdyHeaderBlock> put_headers( spdy_util_.ConstructPutHeaderBlock(GetDefaultUrl(), 0)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *put_headers, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -1698,17 +1708,17 @@ TEST_P(SpdyNetworkTransactionTest, Head) { request.method = "HEAD"; request.url = GURL(GetDefaultUrl()); - scoped_ptr<SpdyHeaderBlock> head_headers( + std::unique_ptr<SpdyHeaderBlock> head_headers( spdy_util_.ConstructHeadHeaderBlock(GetDefaultUrl(), 0)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *head_headers, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -1728,15 +1738,15 @@ TEST_P(SpdyNetworkTransactionTest, Head) { // Test that a simple POST works. TEST_P(SpdyNetworkTransactionTest, Post) { - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 1), // POST upload frame }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -1756,15 +1766,15 @@ TEST_P(SpdyNetworkTransactionTest, Post) { // Test that a POST with a file works. TEST_P(SpdyNetworkTransactionTest, FilePost) { - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 1), // POST upload frame }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -1806,15 +1816,15 @@ TEST_P(SpdyNetworkTransactionTest, UnreadableFilePost) { // Test that a complex POST works. TEST_P(SpdyNetworkTransactionTest, ComplexPost) { - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( GetDefaultUrl(), 1, kUploadDataSize, LOWEST, NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 1), // POST upload frame }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -1835,15 +1845,15 @@ TEST_P(SpdyNetworkTransactionTest, ComplexPost) { // Test that a chunked POST works. TEST_P(SpdyNetworkTransactionTest, ChunkedPost) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 1), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 2), @@ -1871,13 +1881,13 @@ TEST_P(SpdyNetworkTransactionTest, ChunkedPost) { // Test that a chunked POST works with chunks appended after transaction starts. TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> chunk1( + std::unique_ptr<SpdySerializedFrame> chunk1( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> chunk2( + std::unique_ptr<SpdySerializedFrame> chunk2( spdy_util_.ConstructSpdyBodyFrame(1, false)); - scoped_ptr<SpdySerializedFrame> chunk3( + std::unique_ptr<SpdySerializedFrame> chunk3( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -1886,7 +1896,7 @@ TEST_P(SpdyNetworkTransactionTest, DelayedChunkedPost) { CreateMockWrite(*chunk3, 3), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 4), @@ -1938,18 +1948,18 @@ TEST_P(SpdyNetworkTransactionTest, NullPost) { // When request.upload_data_stream is NULL for post, content-length is // expected to be 0. - scoped_ptr<SpdyHeaderBlock> req_block( + std::unique_ptr<SpdyHeaderBlock> req_block( spdy_util_.ConstructPostHeaderBlock(GetDefaultUrl(), 0)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *req_block, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -1972,7 +1982,7 @@ TEST_P(SpdyNetworkTransactionTest, NullPost) { TEST_P(SpdyNetworkTransactionTest, EmptyPost) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); // Create an empty UploadDataStream. - std::vector<scoped_ptr<UploadElementReader>> element_readers; + std::vector<std::unique_ptr<UploadElementReader>> element_readers; ElementsUploadDataStream stream(std::move(element_readers), 0); // Setup the request @@ -1983,18 +1993,18 @@ TEST_P(SpdyNetworkTransactionTest, EmptyPost) { const uint64_t kContentLength = 0; - scoped_ptr<SpdyHeaderBlock> req_block( + std::unique_ptr<SpdyHeaderBlock> req_block( spdy_util_.ConstructPostHeaderBlock(GetDefaultUrl(), kContentLength)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *req_block, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -2015,15 +2025,15 @@ TEST_P(SpdyNetworkTransactionTest, EmptyPost) { // While we're doing a post, the server sends the reply before upload completes. TEST_P(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructChunkedSpdyPost(NULL, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 3), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -2063,9 +2073,9 @@ TEST_P(SpdyNetworkTransactionTest, ResponseBeforePostCompletes) { // socket causes the TCP write to return zero. This test checks that the client // tries to queue up the RST_STREAM frame again. TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*req.get(), 0, SYNCHRONOUS), @@ -2073,7 +2083,7 @@ TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { CreateMockWrite(*rst.get(), 3, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp.get(), 1, ASYNC), @@ -2100,15 +2110,15 @@ TEST_P(SpdyNetworkTransactionTest, SocketWriteReturnsZero) { // Test that the transaction doesn't crash when we don't have a reply. TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*body, 1), MockRead(ASYNC, 0, 3) // EOF }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2), @@ -2124,19 +2134,19 @@ TEST_P(SpdyNetworkTransactionTest, ResponseWithoutSynReply) { // Test that the transaction doesn't crash when we get two replies on the same // stream ID. See http://crbug.com/45639. TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), }; - scoped_ptr<SpdySerializedFrame> resp0( + std::unique_ptr<SpdySerializedFrame> resp0( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp0, 1), CreateMockRead(*resp1, 2), @@ -2171,9 +2181,9 @@ TEST_P(SpdyNetworkTransactionTest, ResponseWithTwoSynReplies) { TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2), @@ -2182,9 +2192,9 @@ TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { const char* const headers[] = { "transfer-encoding", "chunked" }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(headers, 1, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -2205,23 +2215,23 @@ TEST_P(SpdyNetworkTransactionTest, ResetReplyWithTransferEncoding) { TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); const char* const headers[] = { "transfer-encoding", "chunked" }; - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(headers, arraysize(headers) / 2, 2, 1, GetDefaultUrlWithPath("/1").c_str())); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -2245,13 +2255,13 @@ TEST_P(SpdyNetworkTransactionTest, ResetPushWithTransferEncoding) { TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp), @@ -2285,16 +2295,16 @@ TEST_P(SpdyNetworkTransactionTest, CancelledTransaction) { // Verify that the client sends a Rst Frame upon cancelling the stream. TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*req, 0, SYNCHRONOUS), CreateMockWrite(*rst, 2, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), @@ -2326,7 +2336,7 @@ TEST_P(SpdyNetworkTransactionTest, CancelledTransactionSendRst) { // to start another transaction on a session that is closing down. See // http://crbug.com/47455 TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req)}; MockWrite writes2[] = {CreateMockWrite(*req, 0)}; @@ -2339,7 +2349,7 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { 0x07, 'h', 'e', 'l', 'l', 'o', '!', }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -2391,13 +2401,13 @@ TEST_P(SpdyNetworkTransactionTest, StartTransactionOnReadCallback) { // transaction. Failures will usually be valgrind errors. See // http://crbug.com/46925 TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp.get(), 1), @@ -2439,21 +2449,21 @@ TEST_P(SpdyNetworkTransactionTest, DeleteSessionOnReadCallback) { // Send a spdy request to www.example.org that gets redirected to www.foo.com. TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) { - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl())); (*headers)["user-agent"] = ""; (*headers)["accept-encoding"] = "gzip, deflate"; - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php")); (*headers2)["user-agent"] = ""; (*headers2)["accept-encoding"] = "gzip, deflate"; // Setup writes/reads to www.example.org - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdySyn(1, *headers2, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReplyRedirect(1)); MockWrite writes[] = { CreateMockWrite(*req, 1), @@ -2464,9 +2474,9 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) { }; // Setup writes/reads to www.foo.com - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes2[] = { CreateMockWrite(*req2, 1), @@ -2484,7 +2494,7 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) { TestDelegate d; { SpdyURLRequestContext spdy_url_request_context(GetParam().protocol); - scoped_ptr<URLRequest> r(spdy_url_request_context.CreateRequest( + std::unique_ptr<URLRequest> r(spdy_url_request_context.CreateRequest( GURL(GetDefaultUrl()), DEFAULT_PRIORITY, &d)); spdy_url_request_context.socket_factory(). AddSocketDataProvider(&data); @@ -2514,22 +2524,22 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectGetRequest) { // Send a spdy request to www.example.org. Get a pushed stream that redirects to // www.foo.com. TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) { - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl())); (*headers)["user-agent"] = ""; (*headers)["accept-encoding"] = "gzip, deflate"; // Setup writes/reads to www.example.org - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> rep(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> rep(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str(), "301 Moved Permanently", "http://www.foo.com/index.php")); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*req, 1), @@ -2544,15 +2554,15 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) { }; // Setup writes/reads to www.foo.com - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock("http://www.foo.com/index.php")); (*headers2)["user-agent"] = ""; (*headers2)["accept-encoding"] = "gzip, deflate"; - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdySyn(1, *headers2, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes2[] = { CreateMockWrite(*req2, 1), @@ -2571,7 +2581,7 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) { TestDelegate d2; SpdyURLRequestContext spdy_url_request_context(GetParam().protocol); { - scoped_ptr<URLRequest> r(spdy_url_request_context.CreateRequest( + std::unique_ptr<URLRequest> r(spdy_url_request_context.CreateRequest( GURL(GetDefaultUrl()), DEFAULT_PRIORITY, &d)); spdy_url_request_context.socket_factory(). AddSocketDataProvider(&data); @@ -2583,7 +2593,7 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) { std::string contents("hello!"); EXPECT_EQ(contents, d.data_received()); - scoped_ptr<URLRequest> r2(spdy_url_request_context.CreateRequest( + std::unique_ptr<URLRequest> r2(spdy_url_request_context.CreateRequest( GURL(GetDefaultUrlWithPath("/foo.dat")), DEFAULT_PRIORITY, &d2)); spdy_url_request_context.socket_factory(). AddSocketDataProvider(&data2); @@ -2608,20 +2618,20 @@ TEST_P(SpdyNetworkTransactionTest, DISABLED_RedirectServerPush) { } TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); MockRead reads[] = { @@ -2651,20 +2661,20 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame) { } TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); MockRead reads[] = { @@ -2694,21 +2704,21 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushBeforeSynReply) { } TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -2737,19 +2747,19 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushSingleDataFrame2) { } TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - scoped_ptr<SpdySerializedFrame> stream2_rst( + std::unique_ptr<SpdySerializedFrame> stream2_rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -2789,25 +2799,25 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushServerAborted) { // Verify that we don't leak streams and that we properly send a reset // if the server pushes the same stream twice. TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> stream3_rst( + std::unique_ptr<SpdySerializedFrame> stream3_rst( spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream3_rst, 4), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); - scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 4, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -2837,30 +2847,30 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushDuplicate) { } TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); static const char kPushedData[] = "pushed my darling hello my baby"; - scoped_ptr<SpdySerializedFrame> stream2_body_base( + std::unique_ptr<SpdySerializedFrame> stream2_body_base( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); const size_t kChunkSize = strlen(kPushedData) / 4; - scoped_ptr<SpdySerializedFrame> stream2_body1( + std::unique_ptr<SpdySerializedFrame> stream2_body1( new SpdySerializedFrame(stream2_body_base->data(), kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame( stream2_body_base->data() + kChunkSize, kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame( stream2_body_base->data() + 2 * kChunkSize, kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame( stream2_body_base->data() + 3 * kChunkSize, stream2_body_base->size() - 3 * kChunkSize, false)); MockRead reads[] = { @@ -2890,30 +2900,30 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrame) { } TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); static const char kPushedData[] = "pushed my darling hello my baby"; - scoped_ptr<SpdySerializedFrame> stream2_body_base( + std::unique_ptr<SpdySerializedFrame> stream2_body_base( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); const size_t kChunkSize = strlen(kPushedData) / 4; - scoped_ptr<SpdySerializedFrame> stream2_body1( + std::unique_ptr<SpdySerializedFrame> stream2_body1( new SpdySerializedFrame(stream2_body_base->data(), kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body2(new SpdySerializedFrame( stream2_body_base->data() + kChunkSize, kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body3(new SpdySerializedFrame( stream2_body_base->data() + 2 * kChunkSize, kChunkSize, false)); - scoped_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame> stream2_body4(new SpdySerializedFrame( stream2_body_base->data() + 3 * kChunkSize, stream2_body_base->size() - 3 * kChunkSize, false)); MockRead reads[] = { @@ -2942,23 +2952,23 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushMultipleDataFrameInterrupted) { } TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway; + std::unique_ptr<SpdySerializedFrame> goaway; if (spdy_util_.spdy_version() == SPDY3) { goaway.reset(spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Push on even stream id.")); } else { goaway.reset(spdy_util_.ConstructSpdyGoAway( - 0, GOAWAY_PROTOCOL_ERROR, "Framer error: 1 (INVALID_CONTROL_FRAME).")); + 0, GOAWAY_PROTOCOL_ERROR, "Framer error: 1 (INVALID_STREAM_ID).")); } MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 3), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 0, GetDefaultUrlWithPath("/foo.dat").c_str())); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -2993,19 +3003,19 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID0) { } TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> stream2_rst( + std::unique_ptr<SpdySerializedFrame> stream2_rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream2_rst, 3), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( NULL, 0, 2, 9, GetDefaultUrlWithPath("/foo.dat").c_str())); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -3042,23 +3052,23 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidAssociatedStreamID9) { } TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> stream2_rst( + std::unique_ptr<SpdySerializedFrame> stream2_rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*stream2_rst, 3), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> incomplete_headers(new SpdyHeaderBlock()); (*incomplete_headers)[spdy_util_.GetStatusKey()] = "200 OK"; (*incomplete_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; (*incomplete_headers)["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_util_.ConstructInitialSpdyPushFrame(std::move(incomplete_headers), 2, 1)); MockRead reads[] = { @@ -3097,19 +3107,19 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushNoURL) { // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY. TEST_P(SpdyNetworkTransactionTest, ServerPushOnPushedStream) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 2, GOAWAY_PROTOCOL_ERROR, "Push on even stream id.")); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 4), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str())); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream2_syn, 2), @@ -3124,19 +3134,19 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushOnPushedStream) { // PUSH_PROMISE on a closed client-initiated stream should trigger RST_STREAM. TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedStream) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_INVALID_STREAM)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*rst, 5), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream1_body, 2), @@ -3168,25 +3178,25 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedStream) { // PUSH_PROMISE on a server-initiated stream should trigger GOAWAY even if // stream is closed. TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 2, GOAWAY_PROTOCOL_ERROR, "Push on even stream id.")); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*goaway, 7), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream2_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, GetDefaultUrlWithPath("/foo.dat").c_str())); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); - scoped_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> stream3_syn(spdy_util_.ConstructSpdyPush( nullptr, 0, 4, 2, GetDefaultUrlWithPath("/bar.dat").c_str())); MockRead reads[] = { @@ -3211,7 +3221,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushOnClosedPushedStream) { EXPECT_TRUE(response.headers.get()); EXPECT_EQ("HTTP/1.1 200", response.headers->GetStatusLine()); - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback2; rv = trans2->Start(&CreateGetPushRequest(), callback2.callback(), @@ -3274,21 +3284,21 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { test_cases[1].expected_headers["hello"] = "bye"; test_cases[2].expected_headers["hello"] = "bye"; - test_cases[0].expected_headers["cookie"] = StringPiece("val1\0val2", 9); + test_cases[0].expected_headers["cookie"] = base::StringPiece("val1\0val2", 9); test_cases[2].expected_headers["cookie"] = "val1,val2"; for (size_t i = 0; i < arraysize(test_cases); ++i) { SpdyTestUtil spdy_test_util(GetParam().protocol, GetParam().priority_to_dependency); spdy_test_util.set_default_url(GURL(GetDefaultUrl())); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_test_util.ConstructSpdyGetSynReply(test_cases[i].extra_headers, test_cases[i].num_headers, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_test_util.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -3315,7 +3325,7 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeaders) { while (headers->EnumerateHeaderLines(&iter, &name, &value)) { SpdyHeaderBlock::StringPieceProxy mutable_header_block_value = header_block[name]; - if (static_cast<StringPiece>(mutable_header_block_value).empty()) { + if (static_cast<base::StringPiece>(mutable_header_block_value).empty()) { mutable_header_block_value = value; } else { std::string joint_value = mutable_header_block_value.as_string(); @@ -3373,9 +3383,10 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { spdy_test_util.set_default_url(GURL(GetDefaultUrl())); // Construct the request. - scoped_ptr<SpdySerializedFrame> frame_req(spdy_test_util.ConstructSpdyGet( - test_cases[i].extra_headers[0], test_cases[i].num_headers[0], 1, LOWEST, - true)); + std::unique_ptr<SpdySerializedFrame> frame_req( + spdy_test_util.ConstructSpdyGet(test_cases[i].extra_headers[0], + test_cases[i].num_headers[0], 1, LOWEST, + true)); MockWrite writes[] = { CreateMockWrite(*frame_req, 0), @@ -3386,10 +3397,10 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyHeadersVary) { AppendToHeaderBlock(test_cases[i].extra_headers[1], test_cases[i].num_headers[1], &reply_headers); - scoped_ptr<SpdySerializedFrame> frame_reply( + std::unique_ptr<SpdySerializedFrame> frame_reply( spdy_test_util.ConstructSpdyReply(1, reply_headers)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_test_util.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*frame_reply, 1), @@ -3468,9 +3479,9 @@ TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { GetParam().priority_to_dependency); spdy_test_util.set_default_url(GURL(GetDefaultUrl())); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_test_util.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_test_util.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 2), @@ -3480,7 +3491,7 @@ TEST_P(SpdyNetworkTransactionTest, InvalidSynReply) { SpdyHeaderBlock reply_headers; AppendToHeaderBlock( test_cases[i].headers, test_cases[i].num_headers, &reply_headers); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_test_util.ConstructSpdyReply(1, reply_headers)); MockRead reads[] = { CreateMockRead(*resp, 1), MockRead(ASYNC, 0, 3) // EOF @@ -3501,16 +3512,16 @@ TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { return; } - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE).")); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 3), }; // This is the length field that's too short. - scoped_ptr<SpdySerializedFrame> syn_reply_wrong_length( + std::unique_ptr<SpdySerializedFrame> syn_reply_wrong_length( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); size_t right_size = syn_reply_wrong_length->size() - @@ -3519,7 +3530,7 @@ TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionError) { test::SetFrameLength(syn_reply_wrong_length.get(), wrong_size, spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { MockRead(ASYNC, syn_reply_wrong_length->data(), @@ -3540,14 +3551,14 @@ TEST_P(SpdyNetworkTransactionTest, CorruptFrameSessionErrorSpdy4) { return; } - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( - 0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE).")); + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + 0, GOAWAY_COMPRESSION_ERROR, "Framer error: 6 (DECOMPRESS_FAILURE).")); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)}; // This is the length field that's too short. - scoped_ptr<SpdySerializedFrame> syn_reply_wrong_length( + std::unique_ptr<SpdySerializedFrame> syn_reply_wrong_length( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); size_t right_size = syn_reply_wrong_length->size() - @@ -3575,14 +3586,14 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) { // Decompression failures are a stream error in SPDY3. return; } - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( - 0, GOAWAY_COMPRESSION_ERROR, "Framer error: 5 (DECOMPRESS_FAILURE).")); + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + 0, GOAWAY_COMPRESSION_ERROR, "Framer error: 6 (DECOMPRESS_FAILURE).")); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)}; // Read HEADERS with corrupted payload. - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); memset(resp->data() + 12, 0xcf, resp->size() - 12); MockRead reads[] = {CreateMockRead(*resp, 1)}; @@ -3596,15 +3607,15 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayOnDecompressionFailure) { } TEST_P(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_FRAME_SIZE_ERROR, - "Framer error: 12 (INVALID_CONTROL_FRAME_SIZE).")); + "Framer error: 14 (INVALID_CONTROL_FRAME_SIZE).")); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2)}; // Read WINDOW_UPDATE with incorrectly-sized payload. - scoped_ptr<SpdySerializedFrame> bad_window_update( + std::unique_ptr<SpdySerializedFrame> bad_window_update( spdy_util_.ConstructSpdyWindowUpdate(1, 1)); test::SetFrameLength(bad_window_update.get(), bad_window_update->size() - 1, @@ -3621,7 +3632,7 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayOnFrameSizeError) { // Test that we shutdown correctly on write errors. TEST_P(SpdyNetworkTransactionTest, WriteError) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { // We'll write 10 bytes successfully @@ -3651,17 +3662,17 @@ TEST_P(SpdyNetworkTransactionTest, WriteError) { // Test that partial writes work. TEST_P(SpdyNetworkTransactionTest, PartialWrite) { // Chop the SYN_STREAM frame into 5 chunks. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); const int kChunks = 5; - scoped_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks)); + std::unique_ptr<MockWrite[]> writes(ChopWriteFrame(*req.get(), kChunks)); for (int i = 0; i < kChunks; ++i) { writes[i].sequence_number = i; } - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, kChunks), @@ -3684,13 +3695,13 @@ TEST_P(SpdyNetworkTransactionTest, NetLog) { static const char* const kExtraHeaders[] = { "user-agent", "Chrome", }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(kExtraHeaders, 1, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -3777,14 +3788,14 @@ TEST_P(SpdyNetworkTransactionTest, NetLog) { TEST_P(SpdyNetworkTransactionTest, BufferFull) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; // 2 data frames in a single read. - scoped_ptr<SpdySerializedFrame> data_frame_1( + std::unique_ptr<SpdySerializedFrame> data_frame_1( framer.CreateDataFrame(1, "goodby", 6, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> data_frame_2( + std::unique_ptr<SpdySerializedFrame> data_frame_2( framer.CreateDataFrame(1, "e worl", 6, DATA_FLAG_NONE)); const SpdySerializedFrame* data_frames[2] = { data_frame_1.get(), data_frame_2.get(), @@ -3793,10 +3804,10 @@ TEST_P(SpdyNetworkTransactionTest, BufferFull) { int combined_data_frames_len = CombineFrames(data_frames, arraysize(data_frames), combined_data_frames, arraysize(combined_data_frames)); - scoped_ptr<SpdySerializedFrame> last_frame( + std::unique_ptr<SpdySerializedFrame> last_frame( framer.CreateDataFrame(1, "d", 1, DATA_FLAG_FIN)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -3870,14 +3881,14 @@ TEST_P(SpdyNetworkTransactionTest, BufferFull) { TEST_P(SpdyNetworkTransactionTest, Buffering) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; // 4 data frames in a single read. - scoped_ptr<SpdySerializedFrame> data_frame( + std::unique_ptr<SpdySerializedFrame> data_frame( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> data_frame_fin( + std::unique_ptr<SpdySerializedFrame> data_frame_fin( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN)); const SpdySerializedFrame* data_frames[4] = { data_frame.get(), data_frame.get(), data_frame.get(), @@ -3887,7 +3898,7 @@ TEST_P(SpdyNetworkTransactionTest, Buffering) { CombineFrames(data_frames, arraysize(data_frames), combined_data_frames, arraysize(combined_data_frames)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -3962,16 +3973,16 @@ TEST_P(SpdyNetworkTransactionTest, Buffering) { TEST_P(SpdyNetworkTransactionTest, BufferedAll) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; // 5 data frames in a single read. - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> data_frame( + std::unique_ptr<SpdySerializedFrame> data_frame( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> data_frame_fin( + std::unique_ptr<SpdySerializedFrame> data_frame_fin( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_FIN)); const SpdySerializedFrame* frames[5] = {reply.get(), data_frame.get(), data_frame.get(), data_frame.get(), @@ -4048,13 +4059,13 @@ TEST_P(SpdyNetworkTransactionTest, BufferedAll) { TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; // All data frames in a single read. // NOTE: We don't FIN the stream. - scoped_ptr<SpdySerializedFrame> data_frame( + std::unique_ptr<SpdySerializedFrame> data_frame( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); const SpdySerializedFrame* data_frames[4] = { data_frame.get(), data_frame.get(), data_frame.get(), data_frame.get()}; @@ -4062,7 +4073,7 @@ TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { int combined_data_frames_len = CombineFrames(data_frames, arraysize(data_frames), combined_data_frames, arraysize(combined_data_frames)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -4135,17 +4146,17 @@ TEST_P(SpdyNetworkTransactionTest, BufferedClosed) { TEST_P(SpdyNetworkTransactionTest, BufferedCancelled) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4)}; // NOTE: We don't FIN the stream. - scoped_ptr<SpdySerializedFrame> data_frame( + std::unique_ptr<SpdySerializedFrame> data_frame( framer.CreateDataFrame(1, "message", 7, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -4227,20 +4238,24 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.example.org", helper.port()); + url::SchemeHostPort spdy_server("https", host_port_pair.host(), + host_port_pair.port()); + SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); - EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair).empty()); + EXPECT_TRUE(spdy_session_pool->http_server_properties() + ->GetSpdySettings(spdy_server) + .empty()); // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; // Construct the reply. - scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers))); const SpdySettingsIds kSampleId1 = SETTINGS_UPLOAD_BANDWIDTH; @@ -4249,7 +4264,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { unsigned int kSampleValue2 = 0x0b0b0b0b; const SpdySettingsIds kSampleId3 = SETTINGS_ROUND_TRIP_TIME; unsigned int kSampleValue3 = 0x0c0c0c0c; - scoped_ptr<SpdySerializedFrame> settings_frame; + std::unique_ptr<SpdySerializedFrame> settings_frame; { // Construct the SETTINGS frame. SettingsMap settings; @@ -4265,7 +4280,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { settings_frame.reset(spdy_util_.ConstructSpdySettings(settings)); } - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*reply, 1), @@ -4287,7 +4302,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { // Verify we had two persisted settings. const SettingsMap& settings_map = spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair); + spdy_server); ASSERT_EQ(2u, settings_map.size()); // Verify the first persisted setting. @@ -4338,8 +4353,11 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.example.org", helper.port()); - EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair).empty()); + url::SchemeHostPort spdy_server("https", host_port_pair.host(), + host_port_pair.port()); + EXPECT_TRUE(spdy_session_pool->http_server_properties() + ->GetSpdySettings(spdy_server) + .empty()); const SpdySettingsIds kSampleId1 = SETTINGS_MAX_CONCURRENT_STREAMS; unsigned int kSampleValue1 = 0x0a0a0a0a; @@ -4348,37 +4366,31 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { // First add a persisted setting. spdy_session_pool->http_server_properties()->SetSpdySetting( - host_port_pair, - kSampleId1, - SETTINGS_FLAG_PLEASE_PERSIST, - kSampleValue1); + spdy_server, kSampleId1, SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue1); // Next add another persisted setting. spdy_session_pool->http_server_properties()->SetSpdySetting( - host_port_pair, - kSampleId2, - SETTINGS_FLAG_PLEASE_PERSIST, - kSampleValue2); + spdy_server, kSampleId2, SETTINGS_FLAG_PLEASE_PERSIST, kSampleValue2); - EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair).size()); + EXPECT_EQ(2u, spdy_session_pool->http_server_properties() + ->GetSpdySettings(spdy_server) + .size()); // Construct the initial SETTINGS frame. SettingsMap initial_settings; initial_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); - scoped_ptr<SpdySerializedFrame> initial_settings_frame( + std::unique_ptr<SpdySerializedFrame> initial_settings_frame( spdy_util_.ConstructSpdySettings(initial_settings)); // Construct the persisted SETTINGS frame. const SettingsMap& settings = - spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair); - scoped_ptr<SpdySerializedFrame> settings_frame( + spdy_session_pool->http_server_properties()->GetSpdySettings(spdy_server); + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { @@ -4388,13 +4400,13 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { }; // Construct the reply. - scoped_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> reply_headers(new SpdyHeaderBlock()); (*reply_headers)[spdy_util_.GetStatusKey()] = "200"; (*reply_headers)[spdy_util_.GetVersionKey()] = "HTTP/1.1"; - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyFrame(kSynReplyInfo, std::move(reply_headers))); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*reply, 3), @@ -4415,7 +4427,7 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { // Verify we had two persisted settings. const SettingsMap& settings_map = spdy_session_pool->http_server_properties()->GetSpdySettings( - host_port_pair); + spdy_server); ASSERT_EQ(2u, settings_map.size()); // Verify the first persisted setting. @@ -4435,11 +4447,12 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { } TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway()); + std::unique_ptr<SpdySerializedFrame> go_away( + spdy_util_.ConstructSpdyGoAway()); MockRead reads[] = { CreateMockRead(*go_away, 1), }; @@ -4454,11 +4467,11 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayWithActiveStream) { } TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); MockRead reads[] = { CreateMockRead(*resp, 1), MockRead(SYNCHRONOUS, 0, 2) // EOF @@ -4499,7 +4512,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredError) { NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY, BoundNetLog(), GetParam(), nullptr); - scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please.")); MockRead reads[] = { CreateMockRead(*go_away, 0), @@ -4526,7 +4539,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.example.org/"); - scoped_ptr<SpdySessionDependencies> session_deps( + std::unique_ptr<SpdySessionDependencies> session_deps( CreateSpdySessionDependencies(GetParam())); // Do not force SPDY so that second socket can negotiate HTTP/1.1. NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(), @@ -4534,17 +4547,18 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED. const char* url = request.url.spec().c_str(); - scoped_ptr<SpdyHeaderBlock> headers(spdy_util_.ConstructGetHeaderBlock(url)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdyHeaderBlock> headers( + spdy_util_.ConstructGetHeaderBlock(url)); + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true)); MockWrite writes0[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please.")); MockRead reads0[] = {CreateMockRead(*go_away, 1)}; SequencedSocketData data0(reads0, arraysize(reads0), writes0, arraysize(writes0)); - scoped_ptr<SSLSocketDataProvider> ssl_provider0( + std::unique_ptr<SSLSocketDataProvider> ssl_provider0( new SSLSocketDataProvider(ASYNC, OK)); // Expect HTTP/2 protocols too in SSLConfig. ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); @@ -4566,7 +4580,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) { SequencedSocketData data1(reads1, arraysize(reads1), writes1, arraysize(writes1)); - scoped_ptr<SSLSocketDataProvider> ssl_provider1( + std::unique_ptr<SSLSocketDataProvider> ssl_provider1( new SSLSocketDataProvider(ASYNC, OK)); // Expect only HTTP/1.1 protocol in SSLConfig. ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); @@ -4615,7 +4629,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { HttpRequestInfo request; request.method = "GET"; request.url = GURL("https://www.example.org/"); - scoped_ptr<SpdySessionDependencies> session_deps( + std::unique_ptr<SpdySessionDependencies> session_deps( CreateSpdySessionDependencies( GetParam(), ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70"))); @@ -4624,16 +4638,16 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { GetParam(), std::move(session_deps)); // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED. - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyConnect( nullptr, 0, 1, LOWEST, HostPortPair("www.example.org", 443))); MockWrite writes0[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> go_away(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please.")); MockRead reads0[] = {CreateMockRead(*go_away, 1)}; SequencedSocketData data0(reads0, arraysize(reads0), writes0, arraysize(writes0)); - scoped_ptr<SSLSocketDataProvider> ssl_provider0( + std::unique_ptr<SSLSocketDataProvider> ssl_provider0( new SSLSocketDataProvider(ASYNC, OK)); // Expect HTTP/2 protocols too in SSLConfig. ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP2); @@ -4665,7 +4679,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { SequencedSocketData data1(reads1, arraysize(reads1), writes1, arraysize(writes1)); - scoped_ptr<SSLSocketDataProvider> ssl_provider1( + std::unique_ptr<SSLSocketDataProvider> ssl_provider1( new SSLSocketDataProvider(ASYNC, OK)); // Expect only HTTP/1.1 protocol in SSLConfig. ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11); @@ -4674,7 +4688,7 @@ TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) { helper.AddDataWithSSLSocketDataProvider(&data1, std::move(ssl_provider1)); // A third socket is needed for the tunnelled connection. - scoped_ptr<SSLSocketDataProvider> ssl_provider2( + std::unique_ptr<SSLSocketDataProvider> ssl_provider2( new SSLSocketDataProvider(ASYNC, OK)); helper.session_deps()->socket_factory->AddSSLSocketDataProvider( ssl_provider2.get()); @@ -4721,11 +4735,11 @@ TEST_P(SpdyNetworkTransactionTest, ProxyConnect) { "Host: www.example.org:443\r\n" "Proxy-Connection: keep-alive\r\n\r\n"}; const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockWrite writes[] = { @@ -4738,7 +4752,7 @@ TEST_P(SpdyNetworkTransactionTest, ProxyConnect) { CreateMockRead(*body.get(), 4), MockRead(ASYNC, 0, 0, 5), }; - scoped_ptr<SequencedSocketData> data(new SequencedSocketData( + std::unique_ptr<SequencedSocketData> data(new SequencedSocketData( reads, arraysize(reads), writes, arraysize(writes))); helper.AddData(data.get()); @@ -4785,15 +4799,15 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { helper.RunPreTestSetup(); // Construct and send a simple GET request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -4844,11 +4858,11 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { "Host: www.example.org:443\r\n" "Proxy-Connection: keep-alive\r\n\r\n"}; const char kHTTP200[] = {"HTTP/1.1 200 OK\r\n\r\n"}; - scoped_ptr<SpdySerializedFrame> req2(spdy_util_2.ConstructSpdyGet( + std::unique_ptr<SpdySerializedFrame> req2(spdy_util_2.ConstructSpdyGet( GetDefaultUrlWithPath("/foo.dat").c_str(), 1, LOWEST)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_2.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_2.ConstructSpdyBodyFrame(1, true)); MockWrite writes2[] = { @@ -4862,7 +4876,7 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { MockRead(ASYNC, 0, 5) // EOF }; - scoped_ptr<SequencedSocketData> data_proxy(new SequencedSocketData( + std::unique_ptr<SequencedSocketData> data_proxy(new SequencedSocketData( reads2, arraysize(reads2), writes2, arraysize(writes2))); // Create another request to www.example.org, but this time through a proxy. @@ -4870,15 +4884,15 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { request_proxy.method = "GET"; request_proxy.url = GURL(GetDefaultUrlWithPath("/foo.dat")); request_proxy.load_flags = 0; - scoped_ptr<SpdySessionDependencies> ssd_proxy( + std::unique_ptr<SpdySessionDependencies> ssd_proxy( CreateSpdySessionDependencies(GetParam())); // Ensure that this transaction uses the same SpdySessionPool. - scoped_ptr<HttpNetworkSession> session_proxy( + std::unique_ptr<HttpNetworkSession> session_proxy( SpdySessionDependencies::SpdyCreateSession(ssd_proxy.get())); NormalSpdyTransactionHelper helper_proxy(request_proxy, DEFAULT_PRIORITY, BoundNetLog(), GetParam(), NULL); HttpNetworkSessionPeer session_peer(session_proxy.get()); - scoped_ptr<ProxyService> proxy_service( + std::unique_ptr<ProxyService> proxy_service( ProxyService::CreateFixedFromPacResult("PROXY myproxy:70")); session_peer.SetProxyService(proxy_service.get()); helper_proxy.session_deps().swap(ssd_proxy); @@ -4910,9 +4924,9 @@ TEST_P(SpdyNetworkTransactionTest, DirectConnectProxyReconnect) { // This can happen when a server reboots without saying goodbye, or when // we're behind a NAT that masked the RST. TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -4927,12 +4941,12 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { MockRead(ASYNC, 0, 3) // EOF }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); // In all cases the connection will be reset before req3 can be // dispatched, destroying both streams. spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); MockWrite writes1[] = {CreateMockWrite(*req, 0), CreateMockWrite(*req3, 5)}; MockWrite writes2[] = {CreateMockWrite(*req, 0)}; @@ -4961,7 +4975,7 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { helper.RunPreTestSetup(); for (int i = 0; i < 2; ++i) { - scoped_ptr<HttpNetworkTransaction> trans( + std::unique_ptr<HttpNetworkTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); TestCompletionCallback callback; @@ -5002,13 +5016,13 @@ TEST_P(SpdyNetworkTransactionTest, VerifyRetryOnConnectionReset) { // Test that turning SPDY on and off works properly. TEST_P(SpdyNetworkTransactionTest, SpdyOnOffToggle) { HttpStreamFactory::set_spdy_enabled(true); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite spdy_writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead spdy_reads[] = { CreateMockRead(*resp, 1), @@ -5059,14 +5073,14 @@ TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { // The first request will be a bare GET, the second request will be a // GET with an Authorization header. - scoped_ptr<SpdySerializedFrame> req_get( + std::unique_ptr<SpdySerializedFrame> req_get( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); // Will be refused for lack of auth. spdy_util_.UpdateWithStreamDestruction(1); const char* const kExtraAuthorizationHeaders[] = { "authorization", "Basic Zm9vOmJhcg==" }; - scoped_ptr<SpdySerializedFrame> req_get_authorization( + std::unique_ptr<SpdySerializedFrame> req_get_authorization( spdy_util_.ConstructSpdyGet(kExtraAuthorizationHeaders, arraysize(kExtraAuthorizationHeaders) / 2, 3, LOWEST, true)); @@ -5081,15 +5095,15 @@ TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { "www-authenticate", "Basic realm=\"MyRealm\"" }; - scoped_ptr<SpdySerializedFrame> resp_authentication( + std::unique_ptr<SpdySerializedFrame> resp_authentication( spdy_util_.ConstructSpdySynReplyError( "401 Authentication Required", kExtraAuthenticationHeaders, arraysize(kExtraAuthenticationHeaders) / 2, 1)); - scoped_ptr<SpdySerializedFrame> body_authentication( + std::unique_ptr<SpdySerializedFrame> body_authentication( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> resp_data( + std::unique_ptr<SpdySerializedFrame> resp_data( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body_data( + std::unique_ptr<SpdySerializedFrame> body_data( spdy_util_.ConstructSpdyBodyFrame(3, true)); MockRead spdy_reads[] = { CreateMockRead(*resp_authentication, 1), @@ -5146,19 +5160,19 @@ TEST_P(SpdyNetworkTransactionTest, SpdyBasicAuth) { } TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), initial_headers.get()); - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2, 1)); @@ -5166,14 +5180,14 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { late_headers[spdy_util_.GetStatusKey()] = "200"; late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1"; late_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream2_headers( + std::unique_ptr<SpdySerializedFrame> stream2_headers( spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); @@ -5206,30 +5220,30 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithHeaders) { TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { // We push a stream and attempt to claim it before the headers come down. - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), initial_headers.get()); - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); SpdyHeaderBlock late_headers; late_headers[spdy_util_.GetStatusKey()] = "200"; late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1"; late_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream2_headers( + std::unique_ptr<SpdySerializedFrame> stream2_headers( spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); MockRead reads[] = { @@ -5264,7 +5278,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); rv = trans2->Start( &CreateGetPushRequest(), callback.callback(), BoundNetLog()); @@ -5314,32 +5328,32 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushClaimBeforeHeaders) { // TODO(baranovich): HTTP 2 does not allow multiple HEADERS frames TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { // We push a stream and attempt to claim it before the headers come down. - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); if (spdy_util_.spdy_version() < HTTP2) { // In HTTP/2 PUSH_PROMISE headers won't show up in the response headers. (*initial_headers)["alpha"] = "beta"; } spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), initial_headers.get()); - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); SpdyHeaderBlock middle_headers; middle_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream2_headers1( + std::unique_ptr<SpdySerializedFrame> stream2_headers1( spdy_util_.ConstructSpdyResponseHeaders(2, middle_headers, false)); SpdyHeaderBlock late_headers; @@ -5348,11 +5362,11 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { // HTTP/2 eliminates use of the :version header. late_headers[spdy_util_.GetVersionKey()] = "HTTP/1.1"; } - scoped_ptr<SpdySerializedFrame> stream2_headers2( + std::unique_ptr<SpdySerializedFrame> stream2_headers2( spdy_util_.ConstructSpdyResponseHeaders(2, late_headers, false)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); @@ -5391,7 +5405,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); rv = trans2->Start( &CreateGetPushRequest(), callback.callback(), BoundNetLog()); @@ -5446,32 +5460,32 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithTwoHeaderFrames) { TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) { // We push a stream and attempt to claim it before the headers come down. - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> initial_headers(new SpdyHeaderBlock()); spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/foo.dat"), initial_headers.get()); - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_util_.ConstructInitialSpdyPushFrame(std::move(initial_headers), 2, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); SpdyHeaderBlock middle_headers; middle_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream2_headers1( + std::unique_ptr<SpdySerializedFrame> stream2_headers1( spdy_util_.ConstructSpdyResponseHeaders(2, middle_headers, false)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); @@ -5504,7 +5518,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) { // Request the pushed path. At this point, we've received the push, but the // headers are not yet complete. - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); rv = trans2->Start( &CreateGetPushRequest(), callback.callback(), BoundNetLog()); @@ -5544,22 +5558,22 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushWithNoStatusHeaderFrames) { } TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); SpdyHeaderBlock late_headers; late_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream1_headers( + std::unique_ptr<SpdySerializedFrame> stream1_headers( spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), @@ -5580,24 +5594,24 @@ TEST_P(SpdyNetworkTransactionTest, SynReplyWithHeaders) { // trigger a ERR_SPDY_PROTOCOL_ERROR because trailing HEADERS must not be // followed by any DATA frames. TEST_P(SpdyNetworkTransactionTest, SyncReplyDataAfterTrailers) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_util_.ConstructSpdyBodyFrame(1, false)); SpdyHeaderBlock late_headers; late_headers["hello"] = "bye"; - scoped_ptr<SpdySerializedFrame> stream1_headers( + std::unique_ptr<SpdySerializedFrame> stream1_headers( spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false)); - scoped_ptr<SpdySerializedFrame> stream1_body2( + std::unique_ptr<SpdySerializedFrame> stream1_body2( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*stream1_reply, 1), CreateMockRead(*stream1_body, 2), @@ -5645,25 +5659,25 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { SpdyTestUtil spdy_test_util(GetParam().protocol, GetParam().priority_to_dependency); - scoped_ptr<SpdySerializedFrame> stream1_syn( + std::unique_ptr<SpdySerializedFrame> stream1_syn( spdy_test_util.ConstructSpdyGet(url_to_fetch, 1, LOWEST)); - scoped_ptr<SpdySerializedFrame> stream1_body( + std::unique_ptr<SpdySerializedFrame> stream1_body( spdy_test_util.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> push_rst( + std::unique_ptr<SpdySerializedFrame> push_rst( spdy_test_util.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*stream1_syn, 0), CreateMockWrite(*push_rst, 3), }; - scoped_ptr<SpdySerializedFrame> stream1_reply( + std::unique_ptr<SpdySerializedFrame> stream1_reply( spdy_test_util.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> stream2_syn( + std::unique_ptr<SpdySerializedFrame> stream2_syn( spdy_test_util.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> stream2_body( + std::unique_ptr<SpdySerializedFrame> stream2_body( spdy_test_util.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_test_util.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); MockRead reads[] = { @@ -5685,9 +5699,9 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushCrossOriginCorrectness) { // Enable cross-origin push. Since we are not using a proxy, this should // not actually enable cross-origin SPDY push. - scoped_ptr<SpdySessionDependencies> session_deps( + std::unique_ptr<SpdySessionDependencies> session_deps( CreateSpdySessionDependencies(GetParam())); - scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate()); + std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate()); proxy_delegate->set_trusted_spdy_proxy(net::ProxyServer::FromURI( "https://123.45.67.89:443", net::ProxyServer::SCHEME_HTTP)); session_deps->proxy_delegate.reset(proxy_delegate.release()); @@ -5732,21 +5746,22 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) { const char* url_to_fetch = "https://www.example.org"; const char* url_to_push = "https://mail.example.org"; - scoped_ptr<SpdySerializedFrame> headers( + std::unique_ptr<SpdySerializedFrame> headers( spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST)); MockWrite writes[] = { CreateMockWrite(*headers, 0), }; - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame( - 2, kPushedData, strlen(kPushedData), true)); + std::unique_ptr<SpdySerializedFrame> pushed_body( + spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), + true)); MockRead reads[] = { CreateMockRead(*reply, 1), CreateMockRead(*push, 2), @@ -5786,7 +5801,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOrigin) { EXPECT_EQ(1u, spdy_session->unclaimed_pushed_streams_.count(GURL(url_to_push))); - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); HttpRequestInfo push_request; push_request.method = "GET"; @@ -5834,16 +5849,16 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { SpdyTestUtil spdy_util_0(GetParam().protocol, GetParam().priority_to_dependency); - scoped_ptr<SpdySerializedFrame> headers0( + std::unique_ptr<SpdySerializedFrame> headers0( spdy_util_0.ConstructSpdyGet(url_to_fetch0, 1, LOWEST)); MockWrite writes0[] = { CreateMockWrite(*headers0, 0), }; - scoped_ptr<SpdySerializedFrame> reply0( + std::unique_ptr<SpdySerializedFrame> reply0( spdy_util_0.ConstructSpdyGetSynReply(nullptr, 0, 1)); const char kData0[] = "first"; - scoped_ptr<SpdySerializedFrame> body0( + std::unique_ptr<SpdySerializedFrame> body0( spdy_util_0.ConstructSpdyBodyFrame(1, kData0, strlen(kData0), true)); MockRead reads0[] = { CreateMockRead(*reply0, 1), @@ -5857,21 +5872,21 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { SpdyTestUtil spdy_util_1(GetParam().protocol, GetParam().priority_to_dependency); - scoped_ptr<SpdySerializedFrame> headers1( + std::unique_ptr<SpdySerializedFrame> headers1( spdy_util_1.ConstructSpdyGet(url_to_fetch1, 1, LOWEST)); MockWrite writes1[] = { CreateMockWrite(*headers1, 0), }; - scoped_ptr<SpdySerializedFrame> reply1( + std::unique_ptr<SpdySerializedFrame> reply1( spdy_util_1.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_1.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); const char kData1[] = "second"; - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_1.ConstructSpdyBodyFrame(1, kData1, strlen(kData1), true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> pushed_body( + std::unique_ptr<SpdySerializedFrame> pushed_body( spdy_util_1.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), true)); @@ -5899,14 +5914,14 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { // "spdy_pooling.pem" is valid for www.example.org, but not for // docs.example.org. - scoped_ptr<SSLSocketDataProvider> ssl_provider0( + std::unique_ptr<SSLSocketDataProvider> ssl_provider0( new SSLSocketDataProvider(ASYNC, OK)); ssl_provider0->cert = ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"); helper.AddDataWithSSLSocketDataProvider(&data0, std::move(ssl_provider0)); // "wildcard.pem" is valid for both www.example.org and docs.example.org. - scoped_ptr<SSLSocketDataProvider> ssl_provider1( + std::unique_ptr<SSLSocketDataProvider> ssl_provider1( new SSLSocketDataProvider(ASYNC, OK)); ssl_provider1->cert = ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"); @@ -5921,7 +5936,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { // Request |url_to_fetch1|, during which docs.example.org pushes // |url_to_push|, which happens to be for www.example.org, to which there is // already an open connection. - scoped_ptr<HttpNetworkTransaction> trans1( + std::unique_ptr<HttpNetworkTransaction> trans1( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); HttpRequestInfo request1; request1.method = "GET"; @@ -5954,7 +5969,7 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushValidCrossOriginWithOpenSession) { spdy_session1->unclaimed_pushed_streams_.count(GURL(url_to_push))); // Request |url_to_push|, which should be served from the pushed resource. - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(DEFAULT_PRIORITY, helper.session())); HttpRequestInfo push_request; push_request.method = "GET"; @@ -6005,24 +6020,25 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidCrossOrigin) { const char* url_to_fetch = "https://www.example.org"; const char* url_to_push = "https://invalid.example.org"; - scoped_ptr<SpdySerializedFrame> headers( + std::unique_ptr<SpdySerializedFrame> headers( spdy_util_.ConstructSpdyGet(url_to_fetch, 1, LOWEST)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*headers, 0), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, url_to_push)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); const char kPushedData[] = "pushed"; - scoped_ptr<SpdySerializedFrame> pushed_body(spdy_util_.ConstructSpdyBodyFrame( - 2, kPushedData, strlen(kPushedData), true)); + std::unique_ptr<SpdySerializedFrame> pushed_body( + spdy_util_.ConstructSpdyBodyFrame(2, kPushedData, strlen(kPushedData), + true)); MockRead reads[] = { CreateMockRead(*reply, 1), CreateMockRead(*push, 2), @@ -6048,21 +6064,21 @@ TEST_P(SpdyNetworkTransactionTest, ServerPushInvalidCrossOrigin) { TEST_P(SpdyNetworkTransactionTest, RetryAfterRefused) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); // Will be destroyed by the RST before stream 3 starts. spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*req2, 2), }; - scoped_ptr<SpdySerializedFrame> refused( + std::unique_ptr<SpdySerializedFrame> refused( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(3, true)); MockRead reads[] = { CreateMockRead(*refused, 1), @@ -6115,29 +6131,29 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { // req1 is alive when req2 is attempted (during but not after the // |data.RunFor(2);| statement below) but not when req3 is attempted. // The call to spdy_util_.UpdateWithStreamDestruction() reflects this. - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, HIGHEST, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 5, MEDIUM, true)); MockWrite writes[] = { MockWrite(ASYNC, ERR_IO_PENDING, 0), CreateMockWrite(*req1, 1), CreateMockWrite(*req2, 5), CreateMockWrite(*req3, 6), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, true)); - scoped_ptr<SpdySerializedFrame> resp3( + std::unique_ptr<SpdySerializedFrame> resp3( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 5)); - scoped_ptr<SpdySerializedFrame> body3( + std::unique_ptr<SpdySerializedFrame> body3( spdy_util_.ConstructSpdyBodyFrame(5, true)); MockRead reads[] = { CreateMockRead(*resp1, 2), MockRead(ASYNC, ERR_IO_PENDING, 3), @@ -6167,7 +6183,7 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { // Now, start both new transactions HttpRequestInfo info2 = CreateGetRequest(); TestCompletionCallback callback2; - scoped_ptr<HttpNetworkTransaction> trans2( + std::unique_ptr<HttpNetworkTransaction> trans2( new HttpNetworkTransaction(MEDIUM, helper.session())); rv = trans2->Start(&info2, callback2.callback(), BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -6175,7 +6191,7 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { HttpRequestInfo info3 = CreateGetRequest(); TestCompletionCallback callback3; - scoped_ptr<HttpNetworkTransaction> trans3( + std::unique_ptr<HttpNetworkTransaction> trans3( new HttpNetworkTransaction(HIGHEST, helper.session())); rv = trans3->Start(&info3, callback3.callback(), BoundNetLog()); EXPECT_EQ(ERR_IO_PENDING, rv); @@ -6222,15 +6238,16 @@ TEST_P(SpdyNetworkTransactionTest, OutOfOrderSynStream) { // fail under specific circumstances. TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { static int kFrameCount = 2; - scoped_ptr<std::string> content( + std::unique_ptr<std::string> content( new std::string(kMaxSpdyFrameChunkSize, 'a')); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( GetDefaultUrl(), 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0)); - scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame( 1, content->c_str(), content->size(), false)); - scoped_ptr<SpdySerializedFrame> body_end(spdy_util_.ConstructSpdyBodyFrame( - 1, content->c_str(), content->size(), true)); + std::unique_ptr<SpdySerializedFrame> body_end( + spdy_util_.ConstructSpdyBodyFrame(1, content->c_str(), content->size(), + true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -6240,11 +6257,11 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { static const int32_t kDeltaWindowSize = 0xff; static const int kDeltaCount = 4; - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); - scoped_ptr<SpdySerializedFrame> window_update_dummy( + std::unique_ptr<SpdySerializedFrame> window_update_dummy( spdy_util_.ConstructSpdyWindowUpdate(2, kDeltaWindowSize)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); MockRead reads[] = { CreateMockRead(*window_update_dummy, 3), @@ -6260,9 +6277,9 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateReceived) { SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); - std::vector<scoped_ptr<UploadElementReader>> element_readers; + std::vector<std::unique_ptr<UploadElementReader>> element_readers; for (int i = 0; i < kFrameCount; ++i) { - element_readers.push_back(make_scoped_ptr( + element_readers.push_back(base::WrapUnique( new UploadBytesElementReader(content->c_str(), content->size()))); } ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6343,17 +6360,17 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) { SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); initial_settings[SETTINGS_INITIAL_WINDOW_SIZE] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, stream_max_recv_window_size); - scoped_ptr<SpdySerializedFrame> initial_settings_frame( + std::unique_ptr<SpdySerializedFrame> initial_settings_frame( spdy_util_.ConstructSpdySettings(initial_settings)); - scoped_ptr<SpdySerializedFrame> initial_window_update( + std::unique_ptr<SpdySerializedFrame> initial_window_update( spdy_util_.ConstructSpdyWindowUpdate( kSessionFlowControlStreamId, session_max_recv_window_size - default_initial_window_size)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> session_window_update( + std::unique_ptr<SpdySerializedFrame> session_window_update( spdy_util_.ConstructSpdyWindowUpdate(0, session_window_update_delta)); - scoped_ptr<SpdySerializedFrame> stream_window_update( + std::unique_ptr<SpdySerializedFrame> stream_window_update( spdy_util_.ConstructSpdyWindowUpdate(1, stream_window_update_delta)); std::vector<MockWrite> writes; @@ -6366,15 +6383,15 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateSent) { writes.push_back(CreateMockWrite(*req, writes.size())); std::vector<MockRead> reads; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); reads.push_back(CreateMockRead(*resp, writes.size() + reads.size())); - std::vector<scoped_ptr<SpdySerializedFrame>> body_frames; + std::vector<std::unique_ptr<SpdySerializedFrame>> body_frames; const std::string body_data(kChunkSize, 'x'); for (size_t remaining = kTargetSize; remaining != 0;) { size_t frame_size = std::min(remaining, body_data.size()); - body_frames.push_back(make_scoped_ptr(spdy_util_.ConstructSpdyBodyFrame( + body_frames.push_back(base::WrapUnique(spdy_util_.ConstructSpdyBodyFrame( 1, body_data.data(), frame_size, false))); reads.push_back( CreateMockRead(*body_frames.back(), writes.size() + reads.size())); @@ -6446,14 +6463,14 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { // set content-length header correctly) static int kFrameCount = 3; - scoped_ptr<std::string> content( + std::unique_ptr<std::string> content( new std::string(kMaxSpdyFrameChunkSize, 'a')); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( GetDefaultUrl(), 1, kMaxSpdyFrameChunkSize * kFrameCount, LOWEST, NULL, 0)); - scoped_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> body(spdy_util_.ConstructSpdyBodyFrame( 1, content->c_str(), content->size(), false)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); // We're not going to write a data frame with FIN, we'll receive a bad @@ -6465,7 +6482,7 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { }; static const int32_t kDeltaWindowSize = 0x7fffffff; // cause an overflow - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate(1, kDeltaWindowSize)); MockRead reads[] = { CreateMockRead(*window_update, 1), @@ -6474,9 +6491,9 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); - std::vector<scoped_ptr<UploadElementReader>> element_readers; + std::vector<std::unique_ptr<UploadElementReader>> element_readers; for (int i = 0; i < kFrameCount; ++i) { - element_readers.push_back(make_scoped_ptr( + element_readers.push_back(base::WrapUnique( new UploadBytesElementReader(content->c_str(), content->size()))); } ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6521,70 +6538,106 @@ TEST_P(SpdyNetworkTransactionTest, WindowUpdateOverflow) { TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { const int32_t initial_window_size = SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); - // Number of frames we need to send to zero out the window size: data - // frames plus SYN_STREAM plus the last data frame; also we need another - // data frame that we will send once the WINDOW_UPDATE is received, - // therefore +3. - size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; - - // Calculate last frame's size; 0 size data frame is legal. - size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; + // Number of upload data buffers we need to send to zero out the window size + // is the minimal number of upload buffers takes to be bigger than + // |initial_window_size|. + size_t num_upload_buffers = + ceil(static_cast<double>(initial_window_size) / kBufferSize); + // Each upload data buffer consists of |num_frames_in_one_upload_buffer| + // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame, + // which has kBufferSize % kMaxSpdyChunkSize bytes. + size_t num_frames_in_one_upload_buffer = + ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize); // Construct content for a data frame of maximum size. std::string content(kMaxSpdyFrameChunkSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( - GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, - 0)); + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + GetDefaultUrl(), 1, + /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize, + LOWEST, NULL, 0)); // Full frames. - scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 1, content.c_str(), content.size(), false)); - // Last frame to zero out the window size. - scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( - 1, content.c_str(), last_frame_size, false)); + // Last frame in each upload data buffer. + std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); + + // The very last frame before the stalled frames. + std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), + initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); - // Data frame to be sent once WINDOW_UPDATE frame is received. - scoped_ptr<SpdySerializedFrame> body3( + // Data frames to be sent once WINDOW_UPDATE frame is received. + + // If kBufferSize * num_upload_buffers > initial_window_size, + // we need one additional frame to send the rest of 'a'. + std::string last_body(kBufferSize * num_upload_buffers - initial_window_size, + 'a'); + std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame( + 1, last_body.c_str(), last_body.size(), false)); + + // Also send a "hello!" after WINDOW_UPDATE. + std::unique_ptr<SpdySerializedFrame> body5( spdy_util_.ConstructSpdyBodyFrame(1, true)); // Fill in mock writes. - scoped_ptr<MockWrite[]> writes(new MockWrite[num_writes]); size_t i = 0; - writes[i] = CreateMockWrite(*req, i); - for (i = 1; i < num_writes - 2; i++) - writes[i] = CreateMockWrite(*body1, i); - writes[i] = CreateMockWrite(*body2, i); - // The last write must not be attempted until after the WINDOW_UPDATES - // have been received. - writes[i + 1] = CreateMockWrite(*body3, i + 4, SYNCHRONOUS); - - // Construct read frame, give enough space to upload the rest of the - // data. - scoped_ptr<SpdySerializedFrame> session_window_update( - spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); - scoped_ptr<SpdySerializedFrame> window_update( - spdy_util_.ConstructSpdyWindowUpdate(1, kUploadDataSize)); - scoped_ptr<SpdySerializedFrame> reply( + std::vector<MockWrite> writes; + writes.push_back(CreateMockWrite(*req, i++)); + for (size_t j = 0; j < num_upload_buffers; j++) { + for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) { + if (k == num_frames_in_one_upload_buffer - 1 && + kBufferSize % kMaxSpdyFrameChunkSize != 0) { + if (j == num_upload_buffers - 1 && + (initial_window_size % kBufferSize != 0)) { + writes.push_back(CreateMockWrite(*body3, i++)); + } else { + writes.push_back(CreateMockWrite(*body2, i++)); + } + } else { + writes.push_back(CreateMockWrite(*body1, i++)); + } + } + } + + // Fill in mock reads. + std::vector<MockRead> reads; + // Force a pause. + reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++)); + // Construct read frame for window updates that gives enough space to upload + // the rest of the data. + std::unique_ptr<SpdySerializedFrame> session_window_update( + spdy_util_.ConstructSpdyWindowUpdate(0, + kUploadDataSize + last_body.size())); + std::unique_ptr<SpdySerializedFrame> window_update( + spdy_util_.ConstructSpdyWindowUpdate(1, + kUploadDataSize + last_body.size())); + + reads.push_back(CreateMockRead(*session_window_update, i++)); + reads.push_back(CreateMockRead(*window_update, i++)); + + // Stalled frames which can be sent after receiving window updates. + if (last_body.size() > 0) + writes.push_back(CreateMockWrite(*body4, i++)); + writes.push_back(CreateMockWrite(*body5, i++)); + + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); - MockRead reads[] = { - MockRead(ASYNC, ERR_IO_PENDING, i + 1), // Force a pause - CreateMockRead(*session_window_update, i + 2), - CreateMockRead(*window_update, i + 3), - // Now the last write will occur. - CreateMockRead(*reply, i + 5), - CreateMockRead(*body2, i + 6), - CreateMockRead(*body3, i + 7), - MockRead(ASYNC, 0, i + 8) // EOF - }; + reads.push_back(CreateMockRead(*reply, i++)); + reads.push_back(CreateMockRead(*body2, i++)); + reads.push_back(CreateMockRead(*body5, i++)); + reads.push_back(MockRead(ASYNC, 0, i++)); // EOF - SequencedSocketData data(reads, arraysize(reads), writes.get(), num_writes); + SequencedSocketData data(reads.data(), reads.size(), writes.data(), + writes.size()); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - std::string upload_data_string(initial_window_size, 'a'); + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + std::string upload_data_string(kBufferSize * num_upload_buffers, 'a'); upload_data_string.append(kUploadData, kUploadDataSize); - element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader( + element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( upload_data_string.c_str(), upload_data_string.size()))); ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6592,8 +6645,8 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { request.method = "POST"; request.url = GURL(GetDefaultUrl()); request.upload_data_stream = &upload_data_stream; - NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, - BoundNetLog(), GetParam(), NULL); + NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(), + GetParam(), NULL); helper.AddData(&data); helper.RunPreTestSetup(); @@ -6609,10 +6662,17 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { ASSERT_TRUE(stream != NULL); ASSERT_TRUE(stream->stream() != NULL); EXPECT_EQ(0, stream->stream()->send_window_size()); - // All the body data should have been read. - // TODO(satorux): This is because of the weirdness in reading the request - // body in OnSendBodyComplete(). See crbug.com/113107. - EXPECT_TRUE(upload_data_stream.IsEOF()); + if (initial_window_size % kBufferSize != 0) { + // If it does not take whole number of full upload buffer to zero out + // initial window size, then the upload data is not at EOF, because the + // last read must be stalled. + EXPECT_FALSE(upload_data_stream.IsEOF()); + } else { + // All the body data should have been read. + // TODO(satorux): This is because of the weirdness in reading the request + // body in OnSendBodyComplete(). See crbug.com/113107. + EXPECT_TRUE(upload_data_stream.IsEOF()); + } // But the body is not yet fully sent (kUploadData is not yet sent) // since we're send-stalled. EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); @@ -6627,43 +6687,74 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResume) { TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { const int32_t initial_window_size = SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); - - // Number of frames we need to send to zero out the window size: data - // frames plus SYN_STREAM plus the last data frame; also we need another - // data frame that we will send once the SETTING is received, therefore +3. - size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; - - // Calculate last frame's size; 0 size data frame is legal. - size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; + // Number of upload data buffers we need to send to zero out the window size + // is the minimal number of upload buffers takes to be bigger than + // |initial_window_size|. + size_t num_upload_buffers = + ceil(static_cast<double>(initial_window_size) / kBufferSize); + // Each upload data buffer consists of |num_frames_in_one_upload_buffer| + // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame, + // which has kBufferSize % kMaxSpdyChunkSize bytes. + size_t num_frames_in_one_upload_buffer = + ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize); // Construct content for a data frame of maximum size. std::string content(kMaxSpdyFrameChunkSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( - GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, - 0)); + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + GetDefaultUrl(), 1, + /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize, + LOWEST, NULL, 0)); // Full frames. - scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 1, content.c_str(), content.size(), false)); - // Last frame to zero out the window size. - scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( - 1, content.c_str(), last_frame_size, false)); + // Last frame in each upload data buffer. + std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); - // Data frame to be sent once SETTINGS frame is received. - scoped_ptr<SpdySerializedFrame> body3( + // The very last frame before the stalled frames. + std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), + initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); + + // Data frames to be sent once WINDOW_UPDATE frame is received. + + // If kBufferSize * num_upload_buffers > initial_window_size, + // we need one additional frame to send the rest of 'a'. + std::string last_body(kBufferSize * num_upload_buffers - initial_window_size, + 'a'); + std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame( + 1, last_body.c_str(), last_body.size(), false)); + + // Also send a "hello!" after WINDOW_UPDATE. + std::unique_ptr<SpdySerializedFrame> body5( spdy_util_.ConstructSpdyBodyFrame(1, true)); - // Fill in mock reads/writes. - std::vector<MockRead> reads; - std::vector<MockWrite> writes; + // Fill in mock writes. size_t i = 0; + std::vector<MockWrite> writes; writes.push_back(CreateMockWrite(*req, i++)); - while (i < num_writes - 2) - writes.push_back(CreateMockWrite(*body1, i++)); - writes.push_back(CreateMockWrite(*body2, i++)); + for (size_t j = 0; j < num_upload_buffers; j++) { + for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) { + if (k == num_frames_in_one_upload_buffer - 1 && + kBufferSize % kMaxSpdyFrameChunkSize != 0) { + if (j == num_upload_buffers - 1 && + (initial_window_size % kBufferSize != 0)) { + writes.push_back(CreateMockWrite(*body3, i++)); + } else { + writes.push_back(CreateMockWrite(*body2, i++)); + } + } else { + writes.push_back(CreateMockWrite(*body1, i++)); + } + } + } + // Fill in mock reads. + std::vector<MockRead> reads; + // Force a pause. reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++)); // Construct read frame for SETTINGS that gives enough space to upload the @@ -6671,26 +6762,30 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { SettingsMap settings; settings[SETTINGS_INITIAL_WINDOW_SIZE] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size * 2); - scoped_ptr<SpdySerializedFrame> settings_frame_large( + std::unique_ptr<SpdySerializedFrame> settings_frame_large( spdy_util_.ConstructSpdySettings(settings)); reads.push_back(CreateMockRead(*settings_frame_large, i++)); - scoped_ptr<SpdySerializedFrame> session_window_update( - spdy_util_.ConstructSpdyWindowUpdate(0, kUploadDataSize)); + std::unique_ptr<SpdySerializedFrame> session_window_update( + spdy_util_.ConstructSpdyWindowUpdate(0, + last_body.size() + kUploadDataSize)); reads.push_back(CreateMockRead(*session_window_update, i++)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); writes.push_back(CreateMockWrite(*settings_ack, i++)); - writes.push_back(CreateMockWrite(*body3, i++)); + // Stalled frames which can be sent after |settings_ack|. + if (last_body.size() > 0) + writes.push_back(CreateMockWrite(*body4, i++)); + writes.push_back(CreateMockWrite(*body5, i++)); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); reads.push_back(CreateMockRead(*reply, i++)); reads.push_back(CreateMockRead(*body2, i++)); - reads.push_back(CreateMockRead(*body3, i++)); + reads.push_back(CreateMockRead(*body5, i++)); reads.push_back(MockRead(ASYNC, 0, i++)); // EOF // Force all writes to happen before any read, last write will not @@ -6698,10 +6793,10 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { SequencedSocketData data(reads.data(), reads.size(), writes.data(), writes.size()); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - std::string upload_data_string(initial_window_size, 'a'); + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + std::string upload_data_string(kBufferSize * num_upload_buffers, 'a'); upload_data_string.append(kUploadData, kUploadDataSize); - element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader( + element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( upload_data_string.c_str(), upload_data_string.size()))); ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6728,10 +6823,17 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { ASSERT_TRUE(stream->stream() != NULL); EXPECT_EQ(0, stream->stream()->send_window_size()); - // All the body data should have been read. - // TODO(satorux): This is because of the weirdness in reading the request - // body in OnSendBodyComplete(). See crbug.com/113107. - EXPECT_TRUE(upload_data_stream.IsEOF()); + if (initial_window_size % kBufferSize != 0) { + // If it does not take whole number of full upload buffer to zero out + // initial window size, then the upload data is not at EOF, because the + // last read must be stalled. + EXPECT_FALSE(upload_data_stream.IsEOF()); + } else { + // All the body data should have been read. + // TODO(satorux): This is because of the weirdness in reading the request + // body in OnSendBodyComplete(). See crbug.com/113107. + EXPECT_TRUE(upload_data_stream.IsEOF()); + } // But the body is not yet fully sent (kUploadData is not yet sent) // since we're send-stalled. EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); @@ -6751,73 +6853,107 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlStallResumeAfterSettings) { TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { const int32_t initial_window_size = SpdySession::GetDefaultInitialWindowSize(GetParam().protocol); - // Number of frames we need to send to zero out the window size: data - // frames plus SYN_STREAM plus the last data frame; also we need another - // data frame that we will send once the SETTING is received, therefore +3. - size_t num_writes = initial_window_size / kMaxSpdyFrameChunkSize + 3; - - // Calculate last frame's size; 0 size data frame is legal. - size_t last_frame_size = initial_window_size % kMaxSpdyFrameChunkSize; + // Number of upload data buffers we need to send to zero out the window size + // is the minimal number of upload buffers takes to be bigger than + // |initial_window_size|. + size_t num_upload_buffers = + ceil(static_cast<double>(initial_window_size) / kBufferSize); + // Each upload data buffer consists of |num_frames_in_one_upload_buffer| + // frames, each with |kMaxSpdyFrameChunkSize| bytes except the last frame, + // which has kBufferSize % kMaxSpdyChunkSize bytes. + size_t num_frames_in_one_upload_buffer = + ceil(static_cast<double>(kBufferSize) / kMaxSpdyFrameChunkSize); // Construct content for a data frame of maximum size. std::string content(kMaxSpdyFrameChunkSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( - GetDefaultUrl(), 1, initial_window_size + kUploadDataSize, LOWEST, NULL, - 0)); + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + GetDefaultUrl(), 1, + /*content_length=*/kBufferSize * num_upload_buffers + kUploadDataSize, + LOWEST, NULL, 0)); // Full frames. - scoped_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> body1(spdy_util_.ConstructSpdyBodyFrame( 1, content.c_str(), content.size(), false)); - // Last frame to zero out the window size. - scoped_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( - 1, content.c_str(), last_frame_size, false)); + // Last frame in each upload data buffer. + std::unique_ptr<SpdySerializedFrame> body2(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), kBufferSize % kMaxSpdyFrameChunkSize, false)); + + // The very last frame before the stalled frames. + std::unique_ptr<SpdySerializedFrame> body3(spdy_util_.ConstructSpdyBodyFrame( + 1, content.c_str(), + initial_window_size % kBufferSize % kMaxSpdyFrameChunkSize, false)); - // Data frame to be sent once SETTINGS frame is received. - scoped_ptr<SpdySerializedFrame> body3( + // Data frames to be sent once WINDOW_UPDATE frame is received. + + // If kBufferSize * num_upload_buffers > initial_window_size, + // we need one additional frame to send the rest of 'a'. + std::string last_body(kBufferSize * num_upload_buffers - initial_window_size, + 'a'); + std::unique_ptr<SpdySerializedFrame> body4(spdy_util_.ConstructSpdyBodyFrame( + 1, last_body.c_str(), last_body.size(), false)); + + // Also send a "hello!" after WINDOW_UPDATE. + std::unique_ptr<SpdySerializedFrame> body5( spdy_util_.ConstructSpdyBodyFrame(1, true)); - // Fill in mock reads/writes. - std::vector<MockRead> reads; - std::vector<MockWrite> writes; + // Fill in mock writes. size_t i = 0; + std::vector<MockWrite> writes; writes.push_back(CreateMockWrite(*req, i++)); - while (i < num_writes - 2) - writes.push_back(CreateMockWrite(*body1, i++)); - writes.push_back(CreateMockWrite(*body2, i++)); + for (size_t j = 0; j < num_upload_buffers; j++) { + for (size_t k = 0; k < num_frames_in_one_upload_buffer; k++) { + if (k == num_frames_in_one_upload_buffer - 1 && + kBufferSize % kMaxSpdyFrameChunkSize != 0) { + if (j == num_upload_buffers - 1 && + (initial_window_size % kBufferSize != 0)) { + writes.push_back(CreateMockWrite(*body3, i++)); + } else { + writes.push_back(CreateMockWrite(*body2, i++)); + } + } else { + writes.push_back(CreateMockWrite(*body1, i++)); + } + } + } + // Fill in mock reads. + std::vector<MockRead> reads; + // Force a pause. reads.push_back(MockRead(ASYNC, ERR_IO_PENDING, i++)); - // Construct read frame for SETTINGS that makes the send_window_size // negative. SettingsMap new_settings; new_settings[SETTINGS_INITIAL_WINDOW_SIZE] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, initial_window_size / 2); - scoped_ptr<SpdySerializedFrame> settings_frame_small( + std::unique_ptr<SpdySerializedFrame> settings_frame_small( spdy_util_.ConstructSpdySettings(new_settings)); // Construct read frames for WINDOW_UPDATE that makes the send_window_size // positive. - scoped_ptr<SpdySerializedFrame> session_window_update_init_size( + std::unique_ptr<SpdySerializedFrame> session_window_update_init_size( spdy_util_.ConstructSpdyWindowUpdate(0, initial_window_size)); - scoped_ptr<SpdySerializedFrame> window_update_init_size( + std::unique_ptr<SpdySerializedFrame> window_update_init_size( spdy_util_.ConstructSpdyWindowUpdate(1, initial_window_size)); reads.push_back(CreateMockRead(*settings_frame_small, i++)); reads.push_back(CreateMockRead(*session_window_update_init_size, i++)); reads.push_back(CreateMockRead(*window_update_init_size, i++)); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); writes.push_back(CreateMockWrite(*settings_ack, i++)); - writes.push_back(CreateMockWrite(*body3, i++)); + // Stalled frames which can be sent after |settings_ack|. + if (last_body.size() > 0) + writes.push_back(CreateMockWrite(*body4, i++)); + writes.push_back(CreateMockWrite(*body5, i++)); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); reads.push_back(CreateMockRead(*reply, i++)); reads.push_back(CreateMockRead(*body2, i++)); - reads.push_back(CreateMockRead(*body3, i++)); + reads.push_back(CreateMockRead(*body5, i++)); reads.push_back(MockRead(ASYNC, 0, i++)); // EOF // Force all writes to happen before any read, last write will not @@ -6825,10 +6961,10 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { SequencedSocketData data(reads.data(), reads.size(), writes.data(), writes.size()); - std::vector<scoped_ptr<UploadElementReader>> element_readers; - std::string upload_data_string(initial_window_size, 'a'); + std::vector<std::unique_ptr<UploadElementReader>> element_readers; + std::string upload_data_string(kBufferSize * num_upload_buffers, 'a'); upload_data_string.append(kUploadData, kUploadDataSize); - element_readers.push_back(make_scoped_ptr(new UploadBytesElementReader( + element_readers.push_back(base::WrapUnique(new UploadBytesElementReader( upload_data_string.c_str(), upload_data_string.size()))); ElementsUploadDataStream upload_data_stream(std::move(element_readers), 0); @@ -6855,13 +6991,17 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { ASSERT_TRUE(stream->stream() != NULL); EXPECT_EQ(0, stream->stream()->send_window_size()); - // All the body data should have been read. - // TODO(satorux): This is because of the weirdness in reading the request - // body in OnSendBodyComplete(). See crbug.com/113107. - EXPECT_TRUE(upload_data_stream.IsEOF()); - // But the body is not yet fully sent (kUploadData is not yet sent) - // since we're send-stalled. - EXPECT_TRUE(stream->stream()->send_stalled_by_flow_control()); + if (initial_window_size % kBufferSize != 0) { + // If it does not take whole number of full upload buffer to zero out + // initial window size, then the upload data is not at EOF, because the + // last read must be stalled. + EXPECT_FALSE(upload_data_stream.IsEOF()); + } else { + // All the body data should have been read. + // TODO(satorux): This is because of the weirdness in reading the request + // body in OnSendBodyComplete(). See crbug.com/113107. + EXPECT_TRUE(upload_data_stream.IsEOF()); + } // Read in WINDOW_UPDATE or SETTINGS frame. data.Resume(); @@ -6871,16 +7011,16 @@ TEST_P(SpdyNetworkTransactionTest, FlowControlNegativeSendWindowSize) { } TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) { - scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); + std::unique_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); spdy_util_.AddUrlToHeaderBlock("http://www.example.org/a.dat", push_headers.get()); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 3, 1)); MockRead reads[] = {CreateMockRead(*push, 1)}; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_PROTOCOL_ERROR, "Odd push stream id.")); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 2), @@ -6896,21 +7036,21 @@ TEST_P(SpdyNetworkTransactionTest, GoAwayOnOddPushStreamId) { TEST_P(SpdyNetworkTransactionTest, GoAwayOnPushStreamIdLesserOrEqualThanLastAccepted) { - scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( NULL, 0, 4, 1, GetDefaultUrlWithPath("/a.dat").c_str())); - scoped_ptr<SpdyHeaderBlock> push_b_headers(new SpdyHeaderBlock); + std::unique_ptr<SpdyHeaderBlock> push_b_headers(new SpdyHeaderBlock); spdy_util_.AddUrlToHeaderBlock(GetDefaultUrlWithPath("/b.dat"), push_b_headers.get()); - scoped_ptr<SpdySerializedFrame> push_b( + std::unique_ptr<SpdySerializedFrame> push_b( spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_b_headers), 2, 1)); MockRead reads[] = { CreateMockRead(*push_a, 1), CreateMockRead(*push_b, 2), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 4, GOAWAY_PROTOCOL_ERROR, "New push stream id must be greater than the last accepted.")); MockWrite writes[] = { @@ -6936,18 +7076,18 @@ TEST_P(SpdyNetworkTransactionTest, LargeRequest) { request.url = GURL(GetDefaultUrl()); request.extra_headers.SetHeader(kKey, kValue); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl())); (*headers)[kKey] = kValue; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -6968,9 +7108,9 @@ TEST_P(SpdyNetworkTransactionTest, LargeRequest) { // Regression test for https://crbug.com/535629: response header exceeds 16 kB. TEST_P(SpdyNetworkTransactionTest, LargeResponseHeader) { - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(GetDefaultUrl())); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -6983,9 +7123,9 @@ TEST_P(SpdyNetworkTransactionTest, LargeResponseHeader) { const std::string kValue(16 * 1024, 'b'); response_headers[1] = kValue.data(); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(response_headers, 1, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), CreateMockRead(*body, 2), @@ -7011,15 +7151,16 @@ TEST_P(SpdyNetworkTransactionTest, LargeResponseHeader) { class SpdyNetworkTransactionNoTLSUsageCheckTest : public SpdyNetworkTransactionTest { protected: - void RunNoTLSUsageCheckTest(scoped_ptr<SSLSocketDataProvider> ssl_provider) { + void RunNoTLSUsageCheckTest( + std::unique_ptr<SSLSocketDataProvider> ssl_provider) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = {CreateMockWrite(*req, 0)}; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -7056,7 +7197,7 @@ INSTANTIATE_TEST_CASE_P( false))); TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSVersionTooOld) { - scoped_ptr<SSLSocketDataProvider> ssl_provider( + std::unique_ptr<SSLSocketDataProvider> ssl_provider( new SSLSocketDataProvider(ASYNC, OK)); SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3, &ssl_provider->connection_status); @@ -7065,7 +7206,7 @@ TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSVersionTooOld) { } TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSCipherSuiteSucky) { - scoped_ptr<SSLSocketDataProvider> ssl_provider( + std::unique_ptr<SSLSocketDataProvider> ssl_provider( new SSLSocketDataProvider(ASYNC, OK)); // Set to TLS_RSA_WITH_NULL_MD5 SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status); @@ -7076,8 +7217,9 @@ TEST_P(SpdyNetworkTransactionNoTLSUsageCheckTest, TLSCipherSuiteSucky) { class SpdyNetworkTransactionTLSUsageCheckTest : public SpdyNetworkTransactionTest { protected: - void RunTLSUsageCheckTest(scoped_ptr<SSLSocketDataProvider> ssl_provider) { - scoped_ptr<SpdySerializedFrame> goaway( + void RunTLSUsageCheckTest( + std::unique_ptr<SSLSocketDataProvider> ssl_provider) { + std::unique_ptr<SpdySerializedFrame> goaway( spdy_util_.ConstructSpdyGoAway(0, GOAWAY_INADEQUATE_SECURITY, "")); MockWrite writes[] = {CreateMockWrite(*goaway)}; @@ -7104,7 +7246,7 @@ INSTANTIATE_TEST_CASE_P( true))); TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) { - scoped_ptr<SSLSocketDataProvider> ssl_provider( + std::unique_ptr<SSLSocketDataProvider> ssl_provider( new SSLSocketDataProvider(ASYNC, OK)); SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_SSL3, &ssl_provider->connection_status); @@ -7113,7 +7255,7 @@ TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSVersionTooOld) { } TEST_P(SpdyNetworkTransactionTLSUsageCheckTest, TLSCipherSuiteSucky) { - scoped_ptr<SSLSocketDataProvider> ssl_provider( + std::unique_ptr<SSLSocketDataProvider> ssl_provider( new SSLSocketDataProvider(ASYNC, OK)); // Set to TLS_RSA_WITH_NULL_MD5 SSLConnectionStatusSetCipherSuite(0x1, &ssl_provider->connection_status); diff --git a/chromium/net/spdy/spdy_pinnable_buffer_piece.h b/chromium/net/spdy/spdy_pinnable_buffer_piece.h index d0fe866c8ed..01c9d9a2a94 100644 --- a/chromium/net/spdy/spdy_pinnable_buffer_piece.h +++ b/chromium/net/spdy/spdy_pinnable_buffer_piece.h @@ -9,7 +9,6 @@ #include <memory> -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "net/base/net_export.h" @@ -52,7 +51,7 @@ struct NET_EXPORT_PRIVATE SpdyPinnableBufferPiece { const char * buffer_; size_t length_; // Null iff |buffer_| isn't pinned. - scoped_ptr<char[]> storage_; + std::unique_ptr<char[]> storage_; }; } // namespace net diff --git a/chromium/net/spdy/spdy_protocol.cc b/chromium/net/spdy/spdy_protocol.cc index f69e02c10be..4ef25f6b56a 100644 --- a/chromium/net/spdy/spdy_protocol.cc +++ b/chromium/net/spdy/spdy_protocol.cc @@ -4,6 +4,8 @@ #include "net/spdy/spdy_protocol.h" +#include "net/spdy/spdy_bug_tracker.h" + namespace net { bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version, @@ -41,7 +43,7 @@ bool SpdyConstants::IsValidFrameType(SpdyMajorVersion version, return true; } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return false; } @@ -98,7 +100,7 @@ SpdyFrameType SpdyConstants::ParseFrameType(SpdyMajorVersion version, break; } - LOG(DFATAL) << "Unhandled frame type " << frame_type_field; + SPDY_BUG << "Unhandled frame type " << frame_type_field; return DATA; } @@ -124,7 +126,7 @@ int SpdyConstants::SerializeFrameType(SpdyMajorVersion version, case WINDOW_UPDATE: return 9; default: - LOG(DFATAL) << "Serializing unhandled frame type " << frame_type; + SPDY_BUG << "Serializing unhandled frame type " << frame_type; return -1; } case HTTP2: @@ -155,12 +157,12 @@ int SpdyConstants::SerializeFrameType(SpdyMajorVersion version, case BLOCKED: return 11; default: - LOG(DFATAL) << "Serializing unhandled frame type " << frame_type; + SPDY_BUG << "Serializing unhandled frame type " << frame_type; return -1; } } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return -1; } @@ -172,10 +174,39 @@ int SpdyConstants::DataFrameType(SpdyMajorVersion version) { return SerializeFrameType(version, DATA); } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return 0; } +bool SpdyConstants::IsValidHTTP2FrameStreamId( + SpdyStreamId current_frame_stream_id, + SpdyFrameType frame_type_field) { + if (current_frame_stream_id == 0) { + switch (frame_type_field) { + case DATA: + case HEADERS: + case PRIORITY: + case RST_STREAM: + case CONTINUATION: + case PUSH_PROMISE: + // These frame types must specify a stream + return false; + default: + return true; + } + } else { + switch (frame_type_field) { + case GOAWAY: + case SETTINGS: + case PING: + // These frame types must not specify a stream + return false; + default: + return true; + } + } +} + bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version, int setting_id_field) { switch (version) { @@ -209,7 +240,7 @@ bool SpdyConstants::IsValidSettingId(SpdyMajorVersion version, return true; } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return false; } @@ -252,7 +283,7 @@ SpdySettingsIds SpdyConstants::ParseSettingId(SpdyMajorVersion version, break; } - LOG(DFATAL) << "Unhandled setting ID " << setting_id_field; + SPDY_BUG << "Unhandled setting ID " << setting_id_field; return SETTINGS_UPLOAD_BANDWIDTH; } @@ -276,7 +307,7 @@ int SpdyConstants::SerializeSettingId(SpdyMajorVersion version, case SETTINGS_INITIAL_WINDOW_SIZE: return 7; default: - LOG(DFATAL) << "Serializing unhandled setting id " << id; + SPDY_BUG << "Serializing unhandled setting id " << id; return -1; } case HTTP2: @@ -294,11 +325,11 @@ int SpdyConstants::SerializeSettingId(SpdyMajorVersion version, case SETTINGS_MAX_HEADER_LIST_SIZE: return 6; default: - LOG(DFATAL) << "Serializing unhandled setting id " << id; + SPDY_BUG << "Serializing unhandled setting id " << id; return -1; } } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return -1; } @@ -345,7 +376,7 @@ bool SpdyConstants::IsValidRstStreamStatus(SpdyMajorVersion version, return true; } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return false; } @@ -405,7 +436,7 @@ SpdyRstStreamStatus SpdyConstants::ParseRstStreamStatus( break; } - LOG(DFATAL) << "Invalid RST_STREAM status " << rst_stream_status_field; + SPDY_BUG << "Invalid RST_STREAM status " << rst_stream_status_field; return RST_STREAM_PROTOCOL_ERROR; } @@ -436,8 +467,7 @@ int SpdyConstants::SerializeRstStreamStatus( case RST_STREAM_FRAME_TOO_LARGE: return 11; default: - LOG(DFATAL) << "Unhandled RST_STREAM status " - << rst_stream_status; + SPDY_BUG << "Unhandled RST_STREAM status " << rst_stream_status; return -1; } case HTTP2: @@ -465,12 +495,11 @@ int SpdyConstants::SerializeRstStreamStatus( case RST_STREAM_HTTP_1_1_REQUIRED: return 13; default: - LOG(DFATAL) << "Unhandled RST_STREAM status " - << rst_stream_status; + SPDY_BUG << "Unhandled RST_STREAM status " << rst_stream_status; return -1; } } - LOG(DFATAL) << "Unhandled SPDY version " << version; + SPDY_BUG << "Unhandled SPDY version " << version; return -1; } @@ -505,7 +534,7 @@ bool SpdyConstants::IsValidGoAwayStatus(SpdyMajorVersion version, return true; } - LOG(DFATAL) << "Unknown SpdyMajorVersion " << version; + SPDY_BUG << "Unknown SpdyMajorVersion " << version; return false; } @@ -556,7 +585,7 @@ SpdyGoAwayStatus SpdyConstants::ParseGoAwayStatus(SpdyMajorVersion version, break; } - LOG(DFATAL) << "Unhandled GOAWAY status " << goaway_status_field; + SPDY_BUG << "Unhandled GOAWAY status " << goaway_status_field; return GOAWAY_PROTOCOL_ERROR; } @@ -583,7 +612,7 @@ int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version, case GOAWAY_HTTP_1_1_REQUIRED: return 1; // PROTOCOL_ERROR. default: - LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status; + SPDY_BUG << "Serializing unhandled GOAWAY status " << status; return -1; } case HTTP2: @@ -617,11 +646,11 @@ int SpdyConstants::SerializeGoAwayStatus(SpdyMajorVersion version, case GOAWAY_HTTP_1_1_REQUIRED: return 13; default: - LOG(DFATAL) << "Serializing unhandled GOAWAY status " << status; + SPDY_BUG << "Serializing unhandled GOAWAY status " << status; return -1; } } - LOG(DFATAL) << "Unknown SpdyMajorVersion " << version; + SPDY_BUG << "Unknown SpdyMajorVersion " << version; return -1; } @@ -632,7 +661,7 @@ size_t SpdyConstants::GetDataFrameMinimumSize(SpdyMajorVersion version) { case HTTP2: return 9; } - LOG(DFATAL) << "Unhandled SPDY version."; + SPDY_BUG << "Unhandled SPDY version."; return 0; } @@ -643,7 +672,7 @@ size_t SpdyConstants::GetControlFrameHeaderSize(SpdyMajorVersion version) { case HTTP2: return 9; } - LOG(DFATAL) << "Unhandled SPDY version."; + SPDY_BUG << "Unhandled SPDY version."; return 0; } @@ -692,7 +721,7 @@ std::string SpdyConstants::GetVersionString(SpdyMajorVersion version) { case HTTP2: return "h2"; default: - LOG(DFATAL) << "Unsupported SPDY major version: " << version; + SPDY_BUG << "Unsupported SPDY major version: " << version; return "spdy/3"; } } diff --git a/chromium/net/spdy/spdy_protocol.h b/chromium/net/spdy/spdy_protocol.h index e22f89c0260..f8bc425d184 100644 --- a/chromium/net/spdy/spdy_protocol.h +++ b/chromium/net/spdy/spdy_protocol.h @@ -14,12 +14,12 @@ #include <limits> #include <map> +#include <memory> #include <string> #include "base/compiler_specific.h" #include "base/logging.h" #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "base/sys_byteorder.h" #include "net/base/net_export.h" @@ -48,11 +48,16 @@ typedef uint32_t SpdyStreamId; // flow control). const SpdyStreamId kSessionFlowControlStreamId = 0; -// The maxmium possible control frame size allowed by the spec. -const int32_t kSpdyMaxControlFrameSize = (1 << 24) - 1; +// The maxmium possible frame payload size allowed by the spec. +const uint32_t kSpdyMaxFrameSizeLimit = (1 << 24) - 1; -// The maximum control frame size we accept. -const int32_t kControlFrameSizeLimit = 1 << 14; +// The initial value for the maximum frame payload size as per the spec. This is +// the maximum control frame size we accept. +const uint32_t kSpdyInitialFrameSizeLimit = 1 << 14; + +// The initial value for the maximum size of the header list, "unlimited" (max +// unsigned 32-bit int) as per the spec. +const uint32_t kSpdyInitialHeaderListSizeLimit = 0xFFFFFFFF; // Maximum window size for a Spdy stream or session. const int32_t kSpdyMaximumWindowSize = 0x7FFFFFFF; // Max signed 32bit int @@ -282,9 +287,7 @@ enum SpdyFrameType { enum SpdyDataFlags { DATA_FLAG_NONE = 0x00, DATA_FLAG_FIN = 0x01, - DATA_FLAG_END_SEGMENT = 0x02, DATA_FLAG_PADDED = 0x08, - DATA_FLAG_COMPRESSED = 0x20, }; // Flags on control packets @@ -300,7 +303,6 @@ enum SpdyPingFlags { // Used by HEADERS, PUSH_PROMISE, and CONTINUATION. enum SpdyHeadersFlags { - HEADERS_FLAG_END_SEGMENT = 0x02, HEADERS_FLAG_END_HEADERS = 0x04, HEADERS_FLAG_PADDED = 0x08, HEADERS_FLAG_PRIORITY = 0x20, @@ -406,16 +408,20 @@ typedef uint8_t SpdyPriority; const SpdyPriority kV3HighestPriority = 0; const SpdyPriority kV3LowestPriority = 7; +// HTTP/2 stream weights are integers in range [1, 256], as specified in RFC +// 7540 section 5.3.2. Default stream weight is defined in section 5.3.5. +const int kHttp2MinStreamWeight = 1; +const int kHttp2MaxStreamWeight = 256; +const int kHttp2DefaultStreamWeight = 16; + +// Reserved ID for root stream of HTTP/2 stream dependency tree, as specified +// in RFC 7540 section 5.3.1. +const unsigned int kHttp2RootStreamId = 0; + typedef uint64_t SpdyPingId; typedef std::string SpdyProtocolId; -enum class SpdyHeaderValidatorType { - REQUEST, - RESPONSE_HEADER, - RESPONSE_TRAILER -}; - // TODO(hkhalil): Add direct testing for this? It won't increase coverage any, // but is good to do anyway. class NET_EXPORT_PRIVATE SpdyConstants { @@ -441,6 +447,12 @@ class NET_EXPORT_PRIVATE SpdyConstants { // in the given SPDY version. static int DataFrameType(SpdyMajorVersion version); + // (HTTP/2) All standard frame types except WINDOW_UPDATE are + // (stream-specific xor connection-level). Returns false iff we know + // the given frame type does not align with the given streamID. + static bool IsValidHTTP2FrameStreamId(SpdyStreamId current_frame_stream_id, + SpdyFrameType frame_type_field); + // Returns true if a given on-the-wire enumeration of a setting id is valid // for a given protocol version, false otherwise. static bool IsValidSettingId(SpdyMajorVersion version, int setting_id_field); @@ -646,7 +658,7 @@ class NET_EXPORT_PRIVATE SpdyDataIR private: // Used to store data that this SpdyDataIR should own. - scoped_ptr<std::string> data_store_; + std::unique_ptr<std::string> data_store_; base::StringPiece data_; bool padded_; @@ -855,7 +867,7 @@ class NET_EXPORT_PRIVATE SpdyWindowUpdateIR : public SpdyFrameWithStreamIdIR { } int32_t delta() const { return delta_; } void set_delta(int32_t delta) { - DCHECK_LT(0, delta); + DCHECK_LE(0, delta); DCHECK_LE(delta, kSpdyMaximumWindowSize); delta_ = delta; } diff --git a/chromium/net/spdy/spdy_protocol_test.cc b/chromium/net/spdy/spdy_protocol_test.cc index c224818447a..d451f058593 100644 --- a/chromium/net/spdy/spdy_protocol_test.cc +++ b/chromium/net/spdy/spdy_protocol_test.cc @@ -5,10 +5,11 @@ #include "net/spdy/spdy_protocol.h" #include <limits> +#include <memory> -#include "base/memory/scoped_ptr.h" #include "net/spdy/spdy_bitmasks.h" #include "net/spdy/spdy_framer.h" +#include "net/spdy/spdy_test_utils.h" #include "net/test/gtest_util.h" #include "testing/gtest/include/gtest/gtest.h" @@ -19,10 +20,10 @@ namespace { namespace net { TEST(SpdyProtocolDeathTest, TestSpdySettingsAndIdOutOfBounds) { - scoped_ptr<SettingsFlagsAndId> flags_and_id; + std::unique_ptr<SettingsFlagsAndId> flags_and_id; - EXPECT_DFATAL(flags_and_id.reset(new SettingsFlagsAndId(1, 0xffffffff)), - "SPDY setting ID too large."); + EXPECT_SPDY_BUG(flags_and_id.reset(new SettingsFlagsAndId(1, 0xffffffff)), + "SPDY setting ID too large."); // Make sure that we get expected values in opt mode. if (flags_and_id.get() != nullptr) { EXPECT_EQ(1, flags_and_id->flags()); @@ -30,4 +31,33 @@ TEST(SpdyProtocolDeathTest, TestSpdySettingsAndIdOutOfBounds) { } } +TEST(SpdyProtocolTest, IsValidHTTP2FrameStreamId) { + // Stream-specific frames must have non-zero stream ids + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, DATA)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, DATA)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, HEADERS)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, HEADERS)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, PRIORITY)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, PRIORITY)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, RST_STREAM)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, RST_STREAM)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, CONTINUATION)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, CONTINUATION)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, PUSH_PROMISE)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(0, PUSH_PROMISE)); + + // Connection-level frames must have zero stream ids + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(1, GOAWAY)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(0, GOAWAY)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(1, SETTINGS)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(0, SETTINGS)); + EXPECT_FALSE(SpdyConstants::IsValidHTTP2FrameStreamId(1, PING)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(0, PING)); + + // Frames that are neither stream-specific nor connection-level + // should not have their stream id declared invalid + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(1, WINDOW_UPDATE)); + EXPECT_TRUE(SpdyConstants::IsValidHTTP2FrameStreamId(0, WINDOW_UPDATE)); +} + } // namespace net diff --git a/chromium/net/spdy/spdy_proxy_client_socket.cc b/chromium/net/spdy/spdy_proxy_client_socket.cc index 2d75c4cdc56..36bdf392a1d 100644 --- a/chromium/net/spdy/spdy_proxy_client_socket.cc +++ b/chromium/net/spdy/spdy_proxy_client_socket.cc @@ -14,7 +14,7 @@ #include "base/logging.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_util.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "net/base/auth.h" #include "net/base/io_buffer.h" @@ -364,7 +364,7 @@ int SpdyProxyClientSocket::DoSendRequest() { base::Bind(&HttpRequestHeaders::NetLogCallback, base::Unretained(&request_.extra_headers), &request_line)); - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); CreateSpdyHeadersFromHttpRequest(request_, request_.extra_headers, spdy_stream_->GetProtocolVersion(), true, headers.get()); @@ -460,7 +460,7 @@ SpdyResponseHeadersStatus SpdyProxyClientSocket::OnResponseHeadersUpdated( } // Called when data is received or on EOF (if |buffer| is NULL). -void SpdyProxyClientSocket::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +void SpdyProxyClientSocket::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { if (buffer) { net_log_.AddByteTransferEvent(NetLog::TYPE_SOCKET_BYTES_RECEIVED, buffer->GetRemainingSize(), @@ -525,7 +525,7 @@ void SpdyProxyClientSocket::OnClose(int status) { read_callback.Run(status); } else if (!read_callback_.is_null()) { // If we have a read_callback_, the we need to make sure we call it back. - OnDataReceived(scoped_ptr<SpdyBuffer>()); + OnDataReceived(std::unique_ptr<SpdyBuffer>()); } // This may have been deleted by read_callback_, so check first. if (weak_ptr.get() && !write_callback.is_null()) diff --git a/chromium/net/spdy/spdy_proxy_client_socket.h b/chromium/net/spdy/spdy_proxy_client_socket.h index f773666ed22..09c10e402f4 100644 --- a/chromium/net/spdy/spdy_proxy_client_socket.h +++ b/chromium/net/spdy/spdy_proxy_client_socket.h @@ -94,7 +94,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket, void OnRequestHeadersSent() override; SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) override; - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; void OnDataSent() override; void OnTrailers(const SpdyHeaderBlock& trailers) override; void OnClose(int status) override; diff --git a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc index 6e83c3989a3..78c8ce5738d 100644 --- a/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc +++ b/chromium/net/spdy/spdy_proxy_client_socket_unittest.cc @@ -134,14 +134,14 @@ class SpdyProxyClientSocketTest : public PlatformTest, } SpdyTestUtil spdy_util_; - scoped_ptr<SpdyProxyClientSocket> sock_; + std::unique_ptr<SpdyProxyClientSocket> sock_; TestCompletionCallback read_callback_; TestCompletionCallback write_callback_; - scoped_ptr<SequencedSocketData> data_; + std::unique_ptr<SequencedSocketData> data_; BoundTestNetLog net_log_; private: - scoped_ptr<HttpNetworkSession> session_; + std::unique_ptr<HttpNetworkSession> session_; scoped_refptr<IOBuffer> read_buf_; SpdySessionDependencies session_deps_; MockConnect connect_data_; @@ -396,12 +396,12 @@ SpdySerializedFrame* SpdyProxyClientSocketTest::ConstructBodyFrame( // ----------- Connect TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -416,12 +416,12 @@ TEST_P(SpdyProxyClientSocketTest, ConnectSendsCorrectRequest) { } TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -436,12 +436,12 @@ TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthRequested) { } TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectAuthRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectAuthRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -455,14 +455,15 @@ TEST_P(SpdyProxyClientSocketTest, ConnectWithAuthCredentials) { } TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectRedirectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp( + ConstructConnectRedirectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -488,12 +489,12 @@ TEST_P(SpdyProxyClientSocketTest, ConnectRedirects) { } TEST_P(SpdyProxyClientSocketTest, ConnectFails) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { MockRead(ASYNC, 0, 1), // EOF }; @@ -510,14 +511,14 @@ TEST_P(SpdyProxyClientSocketTest, ConnectFails) { // ----------- WasEverUsed TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -537,12 +538,12 @@ TEST_P(SpdyProxyClientSocketTest, WasEverUsedReturnsCorrectValues) { // ----------- GetPeerAddress TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3), // EOF @@ -570,16 +571,16 @@ TEST_P(SpdyProxyClientSocketTest, GetPeerAddressReturnsCorrectValues) { // ----------- Write TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*msg1, 3, SYNCHRONOUS), CreateMockWrite(*msg2, 4, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -594,15 +595,15 @@ TEST_P(SpdyProxyClientSocketTest, WriteSendsDataInDataFrame) { TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) { std::string chunk_data(kMaxSpdyFrameChunkSize, 'x'); - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> chunk( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> chunk( ConstructBodyFrame(chunk_data.data(), chunk_data.length())); MockWrite writes[] = {CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*chunk, 3, SYNCHRONOUS), CreateMockWrite(*chunk, 4, SYNCHRONOUS), CreateMockWrite(*chunk, 5, SYNCHRONOUS)}; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -623,13 +624,13 @@ TEST_P(SpdyProxyClientSocketTest, WriteSplitsLargeDataIntoMultipleFrames) { // ----------- Read TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4), @@ -645,14 +646,14 @@ TEST_P(SpdyProxyClientSocketTest, ReadReadsDataInDataFrame) { } TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4), @@ -672,14 +673,14 @@ TEST_P(SpdyProxyClientSocketTest, ReadDataFromBufferedFrames) { } TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -701,14 +702,14 @@ TEST_P(SpdyProxyClientSocketTest, ReadDataMultipleBufferedFrames) { TEST_P(SpdyProxyClientSocketTest, LargeReadWillMergeDataFromDifferentFrames) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -730,15 +731,15 @@ TEST_P(SpdyProxyClientSocketTest, } TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -764,15 +765,16 @@ TEST_P(SpdyProxyClientSocketTest, MultipleShortReadsThenMoreRead) { } TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg33(ConstructBodyFrame(kMsg33, kLen33)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg33( + ConstructBodyFrame(kMsg33, kLen33)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -796,13 +798,14 @@ TEST_P(SpdyProxyClientSocketTest, ReadWillSplitDataFromLargeFrame) { } TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg333(ConstructBodyFrame(kMsg333, kLen333)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg333( + ConstructBodyFrame(kMsg333, kLen333)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg333, 3, ASYNC), @@ -827,14 +830,14 @@ TEST_P(SpdyProxyClientSocketTest, MultipleReadsFromSameLargeFrame) { } TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectAuthReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -855,14 +858,14 @@ TEST_P(SpdyProxyClientSocketTest, ReadAuthResponseBody) { } TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectErrorReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectErrorReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), CreateMockRead(*msg1, 2, ASYNC), @@ -878,16 +881,16 @@ TEST_P(SpdyProxyClientSocketTest, ReadErrorResponseBody) { // ----------- Reads and Writes TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*msg2, 4, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -916,16 +919,16 @@ TEST_P(SpdyProxyClientSocketTest, AsyncReadAroundWrite) { } TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> msg2(ConstructBodyFrame(kMsg2, kLen2)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), MockWrite(ASYNC, ERR_IO_PENDING, 7), CreateMockWrite(*msg2, 8, ASYNC), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); - scoped_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> msg3(ConstructBodyFrame(kMsg3, kLen3)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 4), @@ -954,12 +957,12 @@ TEST_P(SpdyProxyClientSocketTest, AsyncWriteAroundReads) { // Reading from an already closed socket should return 0 TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3), // EOF @@ -980,12 +983,12 @@ TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsZero) { // Read pending when socket is closed should return 0 TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3), // EOF @@ -1005,14 +1008,14 @@ TEST_P(SpdyProxyClientSocketTest, PendingReadOnCloseReturnsZero) { // Reading from a disconnected socket is an error TEST_P(SpdyProxyClientSocketTest, ReadOnDisconnectSocketReturnsNotConnected) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -1033,13 +1036,13 @@ TEST_P(SpdyProxyClientSocketTest, // Reading buffered data from an already closed socket should return // buffered data, then 0. TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg1, 3, ASYNC), MockRead(ASYNC, 0, 4), // EOF @@ -1065,13 +1068,13 @@ TEST_P(SpdyProxyClientSocketTest, ReadOnClosedSocketReturnsBufferedData) { // Calling Write() on a closed socket is an error TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3), // EOF @@ -1090,15 +1093,15 @@ TEST_P(SpdyProxyClientSocketTest, WriteOnClosedStream) { // Calling Write() on a disconnected socket is an error. TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -1120,13 +1123,13 @@ TEST_P(SpdyProxyClientSocketTest, WriteOnDisconnectedSocket) { // If the socket is closed with a pending Write(), the callback // should be called with ERR_CONNECTION_CLOSED. TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), MockWrite(SYNCHRONOUS, ERR_IO_PENDING, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -1151,14 +1154,14 @@ TEST_P(SpdyProxyClientSocketTest, WritePendingOnClose) { // If the socket is Disconnected with a pending Write(), the callback // should not be called. TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -1185,14 +1188,14 @@ TEST_P(SpdyProxyClientSocketTest, DisconnectWithWritePending) { // If the socket is Disconnected with a pending Read(), the callback // should not be called. TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 3), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 2), }; @@ -1219,13 +1222,13 @@ TEST_P(SpdyProxyClientSocketTest, DisconnectWithReadPending) { // If the socket is Reset when both a read and write are pending, // both should be called back. TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -1261,15 +1264,15 @@ TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePending) { // Makes sure the proxy client socket's source gets the expected NetLog events // and only the expected NetLog events (No SpdySession events). TEST_P(SpdyProxyClientSocketTest, NetLog) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), CreateMockWrite(*rst, 5), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> msg1(ConstructBodyFrame(kMsg1, kLen1)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*msg1, 3, ASYNC), MockRead(SYNCHRONOUS, ERR_IO_PENDING, 4), @@ -1321,11 +1324,10 @@ TEST_P(SpdyProxyClientSocketTest, NetLog) { // deleted when Run is invoked. class DeleteSockCallback : public TestCompletionCallbackBase { public: - explicit DeleteSockCallback(scoped_ptr<SpdyProxyClientSocket>* sock) + explicit DeleteSockCallback(std::unique_ptr<SpdyProxyClientSocket>* sock) : sock_(sock), callback_(base::Bind(&DeleteSockCallback::OnComplete, - base::Unretained(this))) { - } + base::Unretained(this))) {} ~DeleteSockCallback() override {} @@ -1337,7 +1339,7 @@ class DeleteSockCallback : public TestCompletionCallbackBase { SetResult(result); } - scoped_ptr<SpdyProxyClientSocket>* sock_; + std::unique_ptr<SpdyProxyClientSocket>* sock_; CompletionCallback callback_; DISALLOW_COPY_AND_ASSIGN(DeleteSockCallback); @@ -1347,13 +1349,13 @@ class DeleteSockCallback : public TestCompletionCallbackBase { // read callback causes the socket to be deleted, the write callback should // not be called. TEST_P(SpdyProxyClientSocketTest, RstWithReadAndWritePendingDelete) { - scoped_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); + std::unique_ptr<SpdySerializedFrame> conn(ConstructConnectRequestFrame()); MockWrite writes[] = { CreateMockWrite(*conn, 0, SYNCHRONOUS), }; - scoped_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> resp(ConstructConnectReplyFrame()); + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockRead reads[] = { CreateMockRead(*resp, 1, ASYNC), MockRead(ASYNC, ERR_IO_PENDING, 2), diff --git a/chromium/net/spdy/spdy_read_queue.cc b/chromium/net/spdy/spdy_read_queue.cc index 627bf5b83b4..7948ff4480d 100644 --- a/chromium/net/spdy/spdy_read_queue.cc +++ b/chromium/net/spdy/spdy_read_queue.cc @@ -25,7 +25,7 @@ size_t SpdyReadQueue::GetTotalSize() const { return total_size_; } -void SpdyReadQueue::Enqueue(scoped_ptr<SpdyBuffer> buffer) { +void SpdyReadQueue::Enqueue(std::unique_ptr<SpdyBuffer> buffer) { DCHECK_GT(buffer->GetRemainingSize(), 0u); total_size_ += buffer->GetRemainingSize(); queue_.push_back(buffer.release()); diff --git a/chromium/net/spdy/spdy_read_queue.h b/chromium/net/spdy/spdy_read_queue.h index 7c4172cecfb..bf85afbb12c 100644 --- a/chromium/net/spdy/spdy_read_queue.h +++ b/chromium/net/spdy/spdy_read_queue.h @@ -7,9 +7,9 @@ #include <cstddef> #include <deque> +#include <memory> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "net/base/net_export.h" namespace net { @@ -30,7 +30,7 @@ class NET_EXPORT_PRIVATE SpdyReadQueue { size_t GetTotalSize() const; // Enqueues the bytes in |buffer|. - void Enqueue(scoped_ptr<SpdyBuffer> buffer); + void Enqueue(std::unique_ptr<SpdyBuffer> buffer); // Dequeues up to |len| (which must be positive) bytes into // |out|. Returns the number of bytes dequeued. diff --git a/chromium/net/spdy/spdy_read_queue_unittest.cc b/chromium/net/spdy/spdy_read_queue_unittest.cc index 7281f6857cf..468764dabad 100644 --- a/chromium/net/spdy/spdy_read_queue_unittest.cc +++ b/chromium/net/spdy/spdy_read_queue_unittest.cc @@ -6,9 +6,9 @@ #include <algorithm> #include <cstddef> +#include <memory> #include <string> -#include "base/memory/scoped_ptr.h" #include "base/stl_util.h" #include "net/spdy/spdy_buffer.h" #include "testing/gtest/include/gtest/gtest.h" @@ -30,8 +30,8 @@ void EnqueueString(const std::string& data, size_t old_total_size = queue->GetTotalSize(); for (size_t i = 0; i < data.size();) { size_t buffer_size = std::min(data.size() - i, max_buffer_size); - queue->Enqueue( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(data.data() + i, buffer_size))); + queue->Enqueue(std::unique_ptr<SpdyBuffer>( + new SpdyBuffer(data.data() + i, buffer_size))); i += buffer_size; EXPECT_FALSE(queue->IsEmpty()); EXPECT_EQ(old_total_size + i, queue->GetTotalSize()); @@ -46,7 +46,7 @@ std::string DrainToString(size_t max_buffer_size, SpdyReadQueue* queue) { // Pad the buffer so we can detect out-of-bound writes. size_t padding = std::max(static_cast<size_t>(4096), queue->GetTotalSize()); size_t buffer_size_with_padding = padding + max_buffer_size + padding; - scoped_ptr<char[]> buffer(new char[buffer_size_with_padding]); + std::unique_ptr<char[]> buffer(new char[buffer_size_with_padding]); std::memset(buffer.get(), 0, buffer_size_with_padding); char* buffer_data = buffer.get() + padding; diff --git a/chromium/net/spdy/spdy_session.cc b/chromium/net/spdy/spdy_session.cc index d4c6f06c08b..76b74a5e0bd 100644 --- a/chromium/net/spdy/spdy_session.cc +++ b/chromium/net/spdy/spdy_session.cc @@ -22,7 +22,7 @@ #include "base/strings/string_util.h" #include "base/strings/stringprintf.h" #include "base/strings/utf_string_conversions.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/values.h" @@ -61,29 +61,15 @@ const int kHungIntervalSeconds = 10; // Minimum seconds that unclaimed pushed streams will be kept in memory. const int kMinPushedStreamLifetimeSeconds = 300; -scoped_ptr<base::ListValue> SpdyHeaderBlockToListValue( - const SpdyHeaderBlock& headers, - NetLogCaptureMode capture_mode) { - scoped_ptr<base::ListValue> headers_list(new base::ListValue()); - for (SpdyHeaderBlock::const_iterator it = headers.begin(); - it != headers.end(); ++it) { - headers_list->AppendString( - it->first.as_string() + ": " + - ElideHeaderValueForNetLog(capture_mode, it->first.as_string(), - it->second.as_string())); - } - return headers_list; -} - -scoped_ptr<base::Value> NetLogSpdySynStreamSentCallback( +std::unique_ptr<base::Value> NetLogSpdySynStreamSentCallback( const SpdyHeaderBlock* headers, bool fin, bool unidirectional, SpdyPriority spdy_priority, SpdyStreamId stream_id, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode)); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); dict->SetBoolean("fin", fin); dict->SetBoolean("unidirectional", unidirectional); dict->SetInteger("priority", static_cast<int>(spdy_priority)); @@ -91,7 +77,7 @@ scoped_ptr<base::Value> NetLogSpdySynStreamSentCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyHeadersSentCallback( +std::unique_ptr<base::Value> NetLogSpdyHeadersSentCallback( const SpdyHeaderBlock* headers, bool fin, SpdyStreamId stream_id, @@ -100,8 +86,8 @@ scoped_ptr<base::Value> NetLogSpdyHeadersSentCallback( SpdyStreamId parent_stream_id, bool exclusive, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode)); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); dict->SetBoolean("fin", fin); dict->SetInteger("stream_id", stream_id); dict->SetBoolean("has_priority", has_priority); @@ -113,7 +99,7 @@ scoped_ptr<base::Value> NetLogSpdyHeadersSentCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySynStreamReceivedCallback( +std::unique_ptr<base::Value> NetLogSpdySynStreamReceivedCallback( const SpdyHeaderBlock* headers, bool fin, bool unidirectional, @@ -121,8 +107,8 @@ scoped_ptr<base::Value> NetLogSpdySynStreamReceivedCallback( SpdyStreamId stream_id, SpdyStreamId associated_stream, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode)); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); dict->SetBoolean("fin", fin); dict->SetBoolean("unidirectional", unidirectional); dict->SetInteger("priority", static_cast<int>(spdy_priority)); @@ -131,42 +117,42 @@ scoped_ptr<base::Value> NetLogSpdySynStreamReceivedCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback( +std::unique_ptr<base::Value> NetLogSpdySynReplyOrHeadersReceivedCallback( const SpdyHeaderBlock* headers, bool fin, SpdyStreamId stream_id, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode)); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); dict->SetBoolean("fin", fin); dict->SetInteger("stream_id", stream_id); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySessionCloseCallback( +std::unique_ptr<base::Value> NetLogSpdySessionCloseCallback( int net_error, const std::string* description, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("net_error", net_error); dict->SetString("description", *description); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySessionCallback( +std::unique_ptr<base::Value> NetLogSpdySessionCallback( const HostPortProxyPair* host_pair, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetString("host", host_pair->first.ToString()); dict->SetString("proxy", host_pair->second.ToPacString()); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyInitializedCallback( +std::unique_ptr<base::Value> NetLogSpdyInitializedCallback( NetLog::Source source, const NextProto protocol_version, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); if (source.IsValid()) { source.AddToEventParameters(dict.get()); } @@ -175,23 +161,23 @@ scoped_ptr<base::Value> NetLogSpdyInitializedCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySettingsCallback( +std::unique_ptr<base::Value> NetLogSpdySettingsCallback( const HostPortPair& host_port_pair, bool clear_persisted, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetString("host", host_port_pair.ToString()); dict->SetBoolean("clear_persisted", clear_persisted); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySettingCallback( +std::unique_ptr<base::Value> NetLogSpdySettingCallback( SpdySettingsIds id, const SpdyMajorVersion protocol_version, SpdySettingsFlags flags, uint32_t value, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("id", SpdyConstants::SerializeSettingId(protocol_version, id)); dict->SetInteger("flags", flags); @@ -199,12 +185,12 @@ scoped_ptr<base::Value> NetLogSpdySettingCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySendSettingsCallback( +std::unique_ptr<base::Value> NetLogSpdySendSettingsCallback( const SettingsMap* settings, const SpdyMajorVersion protocol_version, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - scoped_ptr<base::ListValue> settings_list(new base::ListValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::ListValue> settings_list(new base::ListValue()); for (SettingsMap::const_iterator it = settings->begin(); it != settings->end(); ++it) { const SpdySettingsIds id = it->first; @@ -220,70 +206,70 @@ scoped_ptr<base::Value> NetLogSpdySendSettingsCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( +std::unique_ptr<base::Value> NetLogSpdyWindowUpdateFrameCallback( SpdyStreamId stream_id, uint32_t delta, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", static_cast<int>(stream_id)); dict->SetInteger("delta", delta); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( +std::unique_ptr<base::Value> NetLogSpdySessionWindowUpdateCallback( int32_t delta, int32_t window_size, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("delta", delta); dict->SetInteger("window_size", window_size); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyDataCallback( +std::unique_ptr<base::Value> NetLogSpdyDataCallback( SpdyStreamId stream_id, int size, bool fin, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", static_cast<int>(stream_id)); dict->SetInteger("size", size); dict->SetBoolean("fin", fin); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyRstCallback( +std::unique_ptr<base::Value> NetLogSpdyRstCallback( SpdyStreamId stream_id, int status, const std::string* description, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", static_cast<int>(stream_id)); dict->SetInteger("status", status); dict->SetString("description", *description); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyPingCallback( +std::unique_ptr<base::Value> NetLogSpdyPingCallback( SpdyPingId unique_id, bool is_ack, const char* type, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("unique_id", static_cast<int>(unique_id)); dict->SetString("type", type); dict->SetBoolean("is_ack", is_ack); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyGoAwayCallback( +std::unique_ptr<base::Value> NetLogSpdyGoAwayCallback( SpdyStreamId last_stream_id, int active_streams, int unclaimed_streams, SpdyGoAwayStatus status, - StringPiece debug_data, + base::StringPiece debug_data, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("last_accepted_stream_id", static_cast<int>(last_stream_id)); dict->SetInteger("active_streams", active_streams); @@ -294,23 +280,23 @@ scoped_ptr<base::Value> NetLogSpdyGoAwayCallback( return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback( +std::unique_ptr<base::Value> NetLogSpdyPushPromiseReceivedCallback( const SpdyHeaderBlock* headers, SpdyStreamId stream_id, SpdyStreamId promised_stream_id, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->Set("headers", SpdyHeaderBlockToListValue(*headers, capture_mode)); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + dict->Set("headers", ElideSpdyHeaderBlockForNetLog(*headers, capture_mode)); dict->SetInteger("id", stream_id); dict->SetInteger("promised_stream_id", promised_stream_id); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback( +std::unique_ptr<base::Value> NetLogSpdyAdoptedPushStreamCallback( SpdyStreamId stream_id, const GURL* url, NetLogCaptureMode capture_mode) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", stream_id); dict->SetString("url", url->spec()); return std::move(dict); @@ -368,6 +354,8 @@ SpdyProtocolErrorDetails MapFramerErrorToProtocolError( return SPDY_ERROR_GOAWAY_FRAME_CORRUPT; case SpdyFramer::SPDY_RST_STREAM_FRAME_CORRUPT: return SPDY_ERROR_RST_STREAM_FRAME_CORRUPT; + case SpdyFramer::SPDY_INVALID_PADDING: + return SPDY_ERROR_INVALID_PADDING; case SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS: return SPDY_ERROR_INVALID_DATA_FRAME_FLAGS; case SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS: @@ -376,6 +364,8 @@ SpdyProtocolErrorDetails MapFramerErrorToProtocolError( return SPDY_ERROR_UNEXPECTED_FRAME; case SpdyFramer::SPDY_INVALID_CONTROL_FRAME_SIZE: return SPDY_ERROR_INVALID_CONTROL_FRAME_SIZE; + case SpdyFramer::SPDY_INVALID_STREAM_ID: + return SPDY_ERROR_INVALID_STREAM_ID; default: NOTREACHED(); return static_cast<SpdyProtocolErrorDetails>(-1); @@ -402,6 +392,8 @@ Error MapFramerErrorToNetError(SpdyFramer::SpdyError err) { return ERR_SPDY_PROTOCOL_ERROR; case SpdyFramer::SPDY_RST_STREAM_FRAME_CORRUPT: return ERR_SPDY_PROTOCOL_ERROR; + case SpdyFramer::SPDY_INVALID_PADDING: + return ERR_SPDY_PROTOCOL_ERROR; case SpdyFramer::SPDY_INVALID_DATA_FRAME_FLAGS: return ERR_SPDY_PROTOCOL_ERROR; case SpdyFramer::SPDY_INVALID_CONTROL_FRAME_FLAGS: @@ -410,6 +402,8 @@ Error MapFramerErrorToNetError(SpdyFramer::SpdyError err) { return ERR_SPDY_PROTOCOL_ERROR; case SpdyFramer::SPDY_INVALID_CONTROL_FRAME_SIZE: return ERR_SPDY_FRAME_SIZE_ERROR; + case SpdyFramer::SPDY_INVALID_STREAM_ID: + return ERR_SPDY_PROTOCOL_ERROR; default: NOTREACHED(); return ERR_SPDY_PROTOCOL_ERROR; @@ -770,7 +764,7 @@ SpdySession::~SpdySession() { } void SpdySession::InitializeWithSocket( - scoped_ptr<ClientSocketHandle> connection, + std::unique_ptr<ClientSocketHandle> connection, SpdySessionPool* pool, bool is_secure, int certificate_error_code) { @@ -946,7 +940,7 @@ int SpdySession::CreateStream(const SpdyStreamRequest& request, return ERR_CONNECTION_CLOSED; } - scoped_ptr<SpdyStream> new_stream( + std::unique_ptr<SpdyStream> new_stream( new SpdyStream(request.type(), GetWeakPtr(), request.url(), request.priority(), stream_initial_send_window_size_, stream_max_recv_window_size_, request.net_log())); @@ -1083,14 +1077,14 @@ bool SpdySession::CloseOneIdleConnection() { void SpdySession::EnqueueStreamWrite( const base::WeakPtr<SpdyStream>& stream, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer) { + std::unique_ptr<SpdyBufferProducer> producer) { DCHECK(frame_type == HEADERS || frame_type == DATA || frame_type == SYN_STREAM); EnqueueWrite(stream->priority(), frame_type, std::move(producer), stream); } -scoped_ptr<SpdySerializedFrame> SpdySession::CreateSynStream( +std::unique_ptr<SpdySerializedFrame> SpdySession::CreateSynStream( SpdyStreamId stream_id, RequestPriority priority, SpdyControlFlags flags, @@ -1105,7 +1099,7 @@ scoped_ptr<SpdySerializedFrame> SpdySession::CreateSynStream( SpdyPriority spdy_priority = ConvertRequestPriorityToSpdyPriority(priority, GetProtocolVersion()); - scoped_ptr<SpdySerializedFrame> syn_frame; + std::unique_ptr<SpdySerializedFrame> syn_frame; // TODO(hkhalil): Avoid copy of |block|. if (GetProtocolVersion() <= SPDY3) { SpdySynStreamIR syn_stream(stream_id); @@ -1158,12 +1152,13 @@ scoped_ptr<SpdySerializedFrame> SpdySession::CreateSynStream( return syn_frame; } -scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, - IOBuffer* data, - int len, - SpdyDataFlags flags) { +std::unique_ptr<SpdyBuffer> SpdySession::CreateDataBuffer( + SpdyStreamId stream_id, + IOBuffer* data, + int len, + SpdyDataFlags flags) { if (availability_state_ == STATE_DRAINING) { - return scoped_ptr<SpdyBuffer>(); + return std::unique_ptr<SpdyBuffer>(); } ActiveStreamMap::const_iterator it = active_streams_.find(stream_id); @@ -1173,7 +1168,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, if (len < 0) { NOTREACHED(); - return scoped_ptr<SpdyBuffer>(); + return std::unique_ptr<SpdyBuffer>(); } int effective_len = std::min(len, kMaxSpdyFrameChunkSize); @@ -1213,7 +1208,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, net_log().AddEvent( NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_STREAM_SEND_WINDOW, NetLog::IntCallback("stream_id", stream_id)); - return scoped_ptr<SpdyBuffer>(); + return std::unique_ptr<SpdyBuffer>(); } effective_len = std::min(effective_len, stream->send_window_size()); @@ -1225,7 +1220,7 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, net_log().AddEvent( NetLog::TYPE_HTTP2_SESSION_STREAM_STALLED_BY_SESSION_SEND_WINDOW, NetLog::IntCallback("stream_id", stream_id)); - return scoped_ptr<SpdyBuffer>(); + return std::unique_ptr<SpdyBuffer>(); } effective_len = std::min(effective_len, session_send_window_size_); @@ -1249,10 +1244,12 @@ scoped_ptr<SpdyBuffer> SpdySession::CreateDataBuffer(SpdyStreamId stream_id, // TODO(mbelshe): reduce memory copies here. DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdySerializedFrame> frame(buffered_spdy_framer_->CreateDataFrame( - stream_id, data->data(), static_cast<uint32_t>(effective_len), flags)); + std::unique_ptr<SpdySerializedFrame> frame( + buffered_spdy_framer_->CreateDataFrame( + stream_id, data->data(), static_cast<uint32_t>(effective_len), + flags)); - scoped_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(std::move(frame))); + std::unique_ptr<SpdyBuffer> data_buffer(new SpdyBuffer(std::move(frame))); // Send window size is based on payload size, so nothing to do if this is // just a FIN with no payload. @@ -1321,7 +1318,7 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it, // TODO(mbelshe): We should send a RST_STREAM control frame here // so that the server can cancel a large send. - scoped_ptr<SpdyStream> owned_stream(it->second.stream); + std::unique_ptr<SpdyStream> owned_stream(it->second.stream); active_streams_.erase(it); if (priority_dependencies_enabled_) priority_dependency_state_.OnStreamDestruction(owned_stream->stream_id()); @@ -1352,7 +1349,7 @@ void SpdySession::CloseActiveStreamIterator(ActiveStreamMap::iterator it, void SpdySession::CloseCreatedStreamIterator(CreatedStreamSet::iterator it, int status) { - scoped_ptr<SpdyStream> owned_stream(*it); + std::unique_ptr<SpdyStream> owned_stream(*it); created_streams_.erase(it); DeleteStream(std::move(owned_stream), status); } @@ -1382,7 +1379,7 @@ void SpdySession::EnqueueResetStreamFrame(SpdyStreamId stream_id, base::Bind(&NetLogSpdyRstCallback, stream_id, status, &description)); DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdySerializedFrame> rst_frame( + std::unique_ptr<SpdySerializedFrame> rst_frame( buffered_spdy_framer_->CreateRstStream(stream_id, status)); EnqueueSessionWrite(priority, RST_STREAM, std::move(rst_frame)); @@ -1573,7 +1570,7 @@ int SpdySession::DoWrite() { } else { // Grab the next frame to send. SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; if (!write_queue_.Dequeue(&frame_type, &producer, &stream)) { write_state_ = WRITE_STATE_IDLE; @@ -1588,7 +1585,7 @@ int SpdySession::DoWrite() { if (frame_type == SYN_STREAM) { CHECK(stream.get()); CHECK_EQ(stream->stream_id(), 0u); - scoped_ptr<SpdyStream> owned_stream = + std::unique_ptr<SpdyStream> owned_stream = ActivateCreatedStream(stream.get()); InsertActivatedStream(std::move(owned_stream)); @@ -1781,9 +1778,10 @@ void SpdySession::DoDrainSession(Error err, const std::string& description) { SpdyGoAwayIR goaway_ir(last_accepted_push_stream_id_, MapNetErrorToGoAwayStatus(err), description); - EnqueueSessionWrite(HIGHEST, GOAWAY, - scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame( - buffered_spdy_framer_->SerializeFrame(goaway_ir)))); + EnqueueSessionWrite( + HIGHEST, GOAWAY, + std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( + buffered_spdy_framer_->SerializeFrame(goaway_ir)))); } availability_state_ = STATE_DRAINING; @@ -1850,14 +1848,14 @@ void SpdySession::MakeUnavailable() { } } -scoped_ptr<base::Value> SpdySession::GetInfoAsValue() const { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); +std::unique_ptr<base::Value> SpdySession::GetInfoAsValue() const { + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("source_id", net_log_.source().id); dict->SetString("host_port_pair", host_port_pair().ToString()); if (!pooled_aliases_.empty()) { - scoped_ptr<base::ListValue> alias_list(new base::ListValue()); + std::unique_ptr<base::ListValue> alias_list(new base::ListValue()); for (const auto& alias : pooled_aliases_) { alias_list->AppendString(alias.host_port_pair().ToString()); } @@ -1941,21 +1939,23 @@ int SpdySession::GetLocalAddress(IPEndPoint* address) const { return rv; } -void SpdySession::EnqueueSessionWrite(RequestPriority priority, - SpdyFrameType frame_type, - scoped_ptr<SpdySerializedFrame> frame) { +void SpdySession::EnqueueSessionWrite( + RequestPriority priority, + SpdyFrameType frame_type, + std::unique_ptr<SpdySerializedFrame> frame) { DCHECK(frame_type == RST_STREAM || frame_type == SETTINGS || frame_type == WINDOW_UPDATE || frame_type == PING || frame_type == GOAWAY); - EnqueueWrite(priority, frame_type, - scoped_ptr<SpdyBufferProducer>(new SimpleBufferProducer( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(std::move(frame))))), - base::WeakPtr<SpdyStream>()); + EnqueueWrite( + priority, frame_type, + std::unique_ptr<SpdyBufferProducer>(new SimpleBufferProducer( + std::unique_ptr<SpdyBuffer>(new SpdyBuffer(std::move(frame))))), + base::WeakPtr<SpdyStream>()); } void SpdySession::EnqueueWrite(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer, + std::unique_ptr<SpdyBufferProducer> producer, const base::WeakPtr<SpdyStream>& stream) { if (availability_state_ == STATE_DRAINING) return; @@ -1975,22 +1975,23 @@ void SpdySession::MaybePostWriteLoop() { } } -void SpdySession::InsertCreatedStream(scoped_ptr<SpdyStream> stream) { +void SpdySession::InsertCreatedStream(std::unique_ptr<SpdyStream> stream) { CHECK_EQ(stream->stream_id(), 0u); CHECK(created_streams_.find(stream.get()) == created_streams_.end()); created_streams_.insert(stream.release()); } -scoped_ptr<SpdyStream> SpdySession::ActivateCreatedStream(SpdyStream* stream) { +std::unique_ptr<SpdyStream> SpdySession::ActivateCreatedStream( + SpdyStream* stream) { CHECK_EQ(stream->stream_id(), 0u); CHECK(created_streams_.find(stream) != created_streams_.end()); stream->set_stream_id(GetNewStreamId()); - scoped_ptr<SpdyStream> owned_stream(stream); + std::unique_ptr<SpdyStream> owned_stream(stream); created_streams_.erase(stream); return owned_stream; } -void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) { +void SpdySession::InsertActivatedStream(std::unique_ptr<SpdyStream> stream) { SpdyStreamId stream_id = stream->stream_id(); CHECK_NE(stream_id, 0u); std::pair<ActiveStreamMap::iterator, bool> result = @@ -2000,7 +2001,7 @@ void SpdySession::InsertActivatedStream(scoped_ptr<SpdyStream> stream) { ignore_result(stream.release()); } -void SpdySession::DeleteStream(scoped_ptr<SpdyStream> stream, int status) { +void SpdySession::DeleteStream(std::unique_ptr<SpdyStream> stream, int status) { if (in_flight_write_stream_.get() == stream.get()) { // If we're deleting the stream for the in-flight write, we still // need to let the write complete, so we clear @@ -2038,6 +2039,11 @@ base::WeakPtr<SpdyStream> SpdySession::GetActivePushStream(const GURL& url) { return active_it->second.stream->GetWeakPtr(); } +url::SchemeHostPort SpdySession::GetServer() { + return url::SchemeHostPort(is_secure_ ? "https" : "http", + host_port_pair().host(), host_port_pair().port()); +} + bool SpdySession::GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated, NextProto* protocol_negotiated) { @@ -2105,14 +2111,13 @@ void SpdySession::OnDataFrameHeader(SpdyStreamId stream_id, void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) { + size_t len) { CHECK(in_io_loop_); DCHECK_LT(len, 1u << 24); if (net_log().IsCapturing()) { net_log().AddEvent( NetLog::TYPE_HTTP2_SESSION_RECV_DATA, - base::Bind(&NetLogSpdyDataCallback, stream_id, len, fin)); + base::Bind(&NetLogSpdyDataCallback, stream_id, len, false)); } // Build the buffer as early as possible so that we go through the @@ -2120,7 +2125,7 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, // |unacked_recv_window_bytes_| properly even when the stream is // inactive (since the other side has still reduced its session send // window). - scoped_ptr<SpdyBuffer> buffer; + std::unique_ptr<SpdyBuffer> buffer; if (data) { DCHECK_GT(len, 0u); CHECK_LE(len, static_cast<size_t>(kReadBufferSize)); @@ -2154,6 +2159,39 @@ void SpdySession::OnStreamFrameData(SpdyStreamId stream_id, stream->OnDataReceived(std::move(buffer)); } +void SpdySession::OnStreamEnd(SpdyStreamId stream_id) { + CHECK(in_io_loop_); + if (net_log().IsCapturing()) { + net_log().AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_DATA, + base::Bind(&NetLogSpdyDataCallback, stream_id, 0, true)); + } + + // Build the buffer as early as possible so that we go through the + // session flow control checks and update + // |unacked_recv_window_bytes_| properly even when the stream is + // inactive (since the other side has still reduced its session send + // window). + std::unique_ptr<SpdyBuffer> buffer; + + ActiveStreamMap::iterator it = active_streams_.find(stream_id); + + // By the time data comes in, the stream may already be inactive. + if (it == active_streams_.end()) + return; + + SpdyStream* stream = it->second.stream; + CHECK_EQ(stream->stream_id(), stream_id); + + if (it->second.waiting_for_syn_reply) { + const std::string& error = "Data received before SYN_REPLY."; + stream->LogStreamError(ERR_SPDY_PROTOCOL_ERROR, error); + ResetStreamIterator(it, RST_STREAM_PROTOCOL_ERROR, error); + return; + } + + stream->OnDataReceived(std::move(buffer)); +} + void SpdySession::OnStreamPadding(SpdyStreamId stream_id, size_t len) { CHECK(in_io_loop_); @@ -2184,7 +2222,7 @@ void SpdySession::OnSettings(bool clear_persisted) { CHECK(in_io_loop_); if (clear_persisted) - http_server_properties_->ClearSpdySettings(host_port_pair()); + http_server_properties_->ClearSpdySettings(GetServer()); if (net_log_.IsCapturing()) { net_log_.AddEvent(NetLog::TYPE_HTTP2_SESSION_RECV_SETTINGS, @@ -2198,7 +2236,7 @@ void SpdySession::OnSettings(bool clear_persisted) { settings_ir.set_is_ack(true); EnqueueSessionWrite( HIGHEST, SETTINGS, - scoped_ptr<SpdySerializedFrame>(new SpdySerializedFrame( + std::unique_ptr<SpdySerializedFrame>(new SpdySerializedFrame( buffered_spdy_framer_->SerializeFrame(settings_ir)))); } } @@ -2208,10 +2246,7 @@ void SpdySession::OnSetting(SpdySettingsIds id, uint8_t flags, uint32_t value) { HandleSetting(id, value); http_server_properties_->SetSpdySetting( - host_port_pair(), - id, - static_cast<SpdySettingsFlags>(flags), - value); + GetServer(), id, static_cast<SpdySettingsFlags>(flags), value); received_settings_ = true; // Log the setting. @@ -2492,7 +2527,7 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id, CHECK_EQ(it->second.stream->stream_id(), stream_id); if (status == 0) { - it->second.stream->OnDataReceived(scoped_ptr<SpdyBuffer>()); + it->second.stream->OnDataReceived(std::unique_ptr<SpdyBuffer>()); } else if (status == RST_STREAM_REFUSED_STREAM) { CloseActiveStreamIterator(it, ERR_SPDY_SERVER_REFUSED_STREAM); } else if (status == RST_STREAM_HTTP_1_1_REQUIRED) { @@ -2516,7 +2551,7 @@ void SpdySession::OnRstStream(SpdyStreamId stream_id, void SpdySession::OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status, - StringPiece debug_data) { + base::StringPiece debug_data) { CHECK(in_io_loop_); // TODO(jgraettinger): UMA histogram on |status|. @@ -2767,7 +2802,7 @@ bool SpdySession::TryCreatePushStream(SpdyStreamId stream_id, return false; } - scoped_ptr<SpdyStream> stream( + std::unique_ptr<SpdyStream> stream( new SpdyStream(SPDY_PUSH_STREAM, GetWeakPtr(), gurl, request_priority, stream_initial_send_window_size_, stream_max_recv_window_size_, net_log_)); @@ -2834,7 +2869,7 @@ void SpdySession::SendInitialData() { if (send_connection_header_prefix_) { DCHECK_EQ(protocol_, kProtoHTTP2); - scoped_ptr<SpdySerializedFrame> connection_header_prefix_frame( + std::unique_ptr<SpdySerializedFrame> connection_header_prefix_frame( new SpdySerializedFrame(const_cast<char*>(kHttp2ConnectionHeaderPrefix), kHttp2ConnectionHeaderPrefixSize, false /* take_ownership */)); @@ -2874,7 +2909,7 @@ void SpdySession::SendInitialData() { // previously told us to use when communicating with them (after // applying them). const SettingsMap& server_settings_map = - http_server_properties_->GetSpdySettings(host_port_pair()); + http_server_properties_->GetSpdySettings(GetServer()); if (server_settings_map.empty()) return; @@ -2902,7 +2937,7 @@ void SpdySession::SendSettings(const SettingsMap& settings) { base::Bind(&NetLogSpdySendSettingsCallback, &settings, protocol_version)); // Create the SETTINGS frame and send it. DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( buffered_spdy_framer_->CreateSettings(settings)); sent_settings_ = true; EnqueueSessionWrite(HIGHEST, SETTINGS, std::move(settings_frame)); @@ -2977,14 +3012,14 @@ void SpdySession::SendWindowUpdateFrame(SpdyStreamId stream_id, delta_window_size)); DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdySerializedFrame> window_update_frame( + std::unique_ptr<SpdySerializedFrame> window_update_frame( buffered_spdy_framer_->CreateWindowUpdate(stream_id, delta_window_size)); EnqueueSessionWrite(priority, WINDOW_UPDATE, std::move(window_update_frame)); } void SpdySession::WritePingFrame(SpdyPingId unique_id, bool is_ack) { DCHECK(buffered_spdy_framer_.get()); - scoped_ptr<SpdySerializedFrame> ping_frame( + std::unique_ptr<SpdySerializedFrame> ping_frame( buffered_spdy_framer_->CreatePingFrame(unique_id, is_ack)); EnqueueSessionWrite(HIGHEST, PING, std::move(ping_frame)); @@ -3081,7 +3116,7 @@ void SpdySession::RecordHistograms() { if (received_settings_) { // Enumerate the saved settings, and set histograms for it. const SettingsMap& settings_map = - http_server_properties_->GetSpdySettings(host_port_pair()); + http_server_properties_->GetSpdySettings(GetServer()); SettingsMap::const_iterator it; for (it = settings_map.begin(); it != settings_map.end(); ++it) { diff --git a/chromium/net/spdy/spdy_session.h b/chromium/net/spdy/spdy_session.h index d99ae0b0f21..328420b1880 100644 --- a/chromium/net/spdy/spdy_session.h +++ b/chromium/net/spdy/spdy_session.h @@ -10,6 +10,7 @@ #include <deque> #include <map> +#include <memory> #include <set> #include <string> #include <vector> @@ -17,7 +18,6 @@ #include "base/gtest_prod_util.h" #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "net/base/host_port_pair.h" @@ -42,6 +42,7 @@ #include "net/spdy/spdy_write_queue.h" #include "net/ssl/ssl_config_service.h" #include "url/gurl.h" +#include "url/scheme_host_port.h" namespace net { @@ -94,10 +95,12 @@ enum SpdyProtocolErrorDetails { SPDY_ERROR_COMPRESS_FAILURE = 6, SPDY_ERROR_GOAWAY_FRAME_CORRUPT = 29, SPDY_ERROR_RST_STREAM_FRAME_CORRUPT = 30, + SPDY_ERROR_INVALID_PADDING = 39, SPDY_ERROR_INVALID_DATA_FRAME_FLAGS = 8, SPDY_ERROR_INVALID_CONTROL_FRAME_FLAGS = 9, SPDY_ERROR_UNEXPECTED_FRAME = 31, SPDY_ERROR_INVALID_CONTROL_FRAME_SIZE = 37, + SPDY_ERROR_INVALID_STREAM_ID = 38, // SpdyRstStreamStatus mappings. // RST_STREAM_INVALID not mapped. STATUS_CODE_PROTOCOL_ERROR = 11, @@ -126,7 +129,7 @@ enum SpdyProtocolErrorDetails { PROTOCOL_ERROR_RECEIVE_WINDOW_VIOLATION = 28, // Next free value. - NUM_SPDY_PROTOCOL_ERROR_DETAILS = 38, + NUM_SPDY_PROTOCOL_ERROR_DETAILS = 40, }; SpdyProtocolErrorDetails NET_EXPORT_PRIVATE MapFramerErrorToProtocolError(SpdyFramer::SpdyError error); @@ -137,7 +140,7 @@ SpdyGoAwayStatus NET_EXPORT_PRIVATE MapNetErrorToGoAwayStatus(Error err); // If these compile asserts fail then SpdyProtocolErrorDetails needs // to be updated with new values, as do the mapping functions above. -static_assert(13 == SpdyFramer::LAST_ERROR, +static_assert(15 == SpdyFramer::LAST_ERROR, "SpdyProtocolErrorDetails / Spdy Errors mismatch"); static_assert(17 == RST_STREAM_NUM_STATUS_CODES, "SpdyProtocolErrorDetails / RstStreamStatus mismatch"); @@ -338,7 +341,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // The session begins reading from |connection| on a subsequent event loop // iteration, so the SpdySession may close immediately afterwards if the first // read of |connection| fails. - void InitializeWithSocket(scoped_ptr<ClientSocketHandle> connection, + void InitializeWithSocket(std::unique_ptr<ClientSocketHandle> connection, SpdySessionPool* pool, bool is_secure, int certificate_error_code); @@ -364,10 +367,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // producer is used to produce its frame. void EnqueueStreamWrite(const base::WeakPtr<SpdyStream>& stream, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer); + std::unique_ptr<SpdyBufferProducer> producer); // Creates and returns a SYN frame for |stream_id|. - scoped_ptr<SpdySerializedFrame> CreateSynStream( + std::unique_ptr<SpdySerializedFrame> CreateSynStream( SpdyStreamId stream_id, RequestPriority priority, SpdyControlFlags flags, @@ -375,10 +378,10 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // Creates and returns a SpdyBuffer holding a data frame with the // given data. May return NULL if stalled by flow control. - scoped_ptr<SpdyBuffer> CreateDataBuffer(SpdyStreamId stream_id, - IOBuffer* data, - int len, - SpdyDataFlags flags); + std::unique_ptr<SpdyBuffer> CreateDataBuffer(SpdyStreamId stream_id, + IOBuffer* data, + int len, + SpdyDataFlags flags); // Close the stream with the given ID, which must exist and be // active. Note that that stream may hold the last reference to the @@ -404,6 +407,9 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // status, such as "resolving host", "connecting", etc. LoadState GetLoadState() const; + // Returns server infomation in the form of (scheme/host/port). + url::SchemeHostPort GetServer(); + // Fills SSL info in |ssl_info| and returns true when SSL is in use. bool GetSSLInfo(SSLInfo* ssl_info, bool* was_npn_negotiated, @@ -454,7 +460,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // Retrieves information on the current state of the SPDY session as a // Value. - scoped_ptr<base::Value> GetInfoAsValue() const; + std::unique_ptr<base::Value> GetInfoAsValue() const; // Indicates whether the session is being reused after having successfully // used to send/receive data in the past or if the underlying socket was idle @@ -790,29 +796,29 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // queue for the session. void EnqueueSessionWrite(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdySerializedFrame> frame); + std::unique_ptr<SpdySerializedFrame> frame); // Puts |producer| associated with |stream| onto the write queue // with the given priority. void EnqueueWrite(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> producer, + std::unique_ptr<SpdyBufferProducer> producer, const base::WeakPtr<SpdyStream>& stream); // Inserts a newly-created stream into |created_streams_|. - void InsertCreatedStream(scoped_ptr<SpdyStream> stream); + void InsertCreatedStream(std::unique_ptr<SpdyStream> stream); // Activates |stream| (which must be in |created_streams_|) by // assigning it an ID and returns it. - scoped_ptr<SpdyStream> ActivateCreatedStream(SpdyStream* stream); + std::unique_ptr<SpdyStream> ActivateCreatedStream(SpdyStream* stream); // Inserts a newly-activated stream into |active_streams_|. - void InsertActivatedStream(scoped_ptr<SpdyStream> stream); + void InsertActivatedStream(std::unique_ptr<SpdyStream> stream); // Remove all internal references to |stream|, call OnClose() on it, // and process any pending stream requests before deleting it. Note // that |stream| may hold the last reference to the session. - void DeleteStream(scoped_ptr<SpdyStream> stream, int status); + void DeleteStream(std::unique_ptr<SpdyStream> stream, int status); // Check if we have a pending pushed-stream for this url // Returns the stream if found (and returns it from the pending @@ -876,8 +882,8 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, bool fin) override; void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override; + size_t len) override; + void OnStreamEnd(SpdyStreamId stream_id) override; void OnStreamPadding(SpdyStreamId stream_id, size_t len) override; SpdyHeadersHandlerInterface* OnHeaderFrameStart( SpdyStreamId stream_id) override; @@ -1022,7 +1028,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, TransportSecurityState* transport_security_state_; // The socket handle for this session. - scoped_ptr<ClientSocketHandle> connection_; + std::unique_ptr<ClientSocketHandle> connection_; // The read buffer used to read data from the socket. scoped_refptr<IOBuffer> read_buffer_; @@ -1072,7 +1078,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, // Data for the frame we are currently sending. // The buffer we're currently writing. - scoped_ptr<SpdyBuffer> in_flight_write_; + std::unique_ptr<SpdyBuffer> in_flight_write_; // The type of the frame in |in_flight_write_|. SpdyFrameType in_flight_write_frame_type_; // The size of the frame in |in_flight_write_|. @@ -1088,7 +1094,7 @@ class NET_EXPORT SpdySession : public BufferedSpdyFramerVisitorInterface, int certificate_error_code_; // Spdy Frame state. - scoped_ptr<BufferedSpdyFramer> buffered_spdy_framer_; + std::unique_ptr<BufferedSpdyFramer> buffered_spdy_framer_; // The state variables. AvailabilityState availability_state_; diff --git a/chromium/net/spdy/spdy_session_pool.cc b/chromium/net/spdy/spdy_session_pool.cc index 1875224e73b..31565a9e08c 100644 --- a/chromium/net/spdy/spdy_session_pool.cc +++ b/chromium/net/spdy/spdy_session_pool.cc @@ -85,7 +85,7 @@ SpdySessionPool::~SpdySessionPool() { base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( const SpdySessionKey& key, - scoped_ptr<ClientSocketHandle> connection, + std::unique_ptr<ClientSocketHandle> connection, const BoundNetLog& net_log, int certificate_error_code, bool is_secure) { @@ -96,7 +96,7 @@ base::WeakPtr<SpdySession> SpdySessionPool::CreateAvailableSessionFromSocket( UMA_HISTOGRAM_ENUMERATION( "Net.SpdySessionGet", IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX); - scoped_ptr<SpdySession> new_session(new SpdySession( + std::unique_ptr<SpdySession> new_session(new SpdySession( key, http_server_properties_, transport_security_state_, verify_domain_authentication_, enable_sending_initial_data_, enable_ping_based_connection_checking_, enable_priority_dependencies_, @@ -254,7 +254,7 @@ void SpdySessionPool::RemoveUnavailableSession( SessionSet::iterator it = sessions_.find(unavailable_session.get()); CHECK(it != sessions_.end()); - scoped_ptr<SpdySession> owned_session(*it); + std::unique_ptr<SpdySession> owned_session(*it); sessions_.erase(it); } @@ -326,8 +326,9 @@ void SpdySessionPool::UnregisterUnclaimedPushedStream( DCHECK_EQ(1u, removed); } -scoped_ptr<base::Value> SpdySessionPool::SpdySessionPoolInfoToValue() const { - scoped_ptr<base::ListValue> list(new base::ListValue()); +std::unique_ptr<base::Value> SpdySessionPool::SpdySessionPoolInfoToValue() + const { + std::unique_ptr<base::ListValue> list(new base::ListValue()); for (AvailableSessionMap::const_iterator it = available_sessions_.begin(); it != available_sessions_.end(); ++it) { diff --git a/chromium/net/spdy/spdy_session_pool.h b/chromium/net/spdy/spdy_session_pool.h index eeae3148f54..13664dc527f 100644 --- a/chromium/net/spdy/spdy_session_pool.h +++ b/chromium/net/spdy/spdy_session_pool.h @@ -86,7 +86,7 @@ class NET_EXPORT SpdySessionPool // immediately afterwards if the first read of |connection| fails. base::WeakPtr<SpdySession> CreateAvailableSessionFromSocket( const SpdySessionKey& key, - scoped_ptr<ClientSocketHandle> connection, + std::unique_ptr<ClientSocketHandle> connection, const BoundNetLog& net_log, int certificate_error_code, bool is_secure); @@ -131,7 +131,7 @@ class NET_EXPORT SpdySessionPool SpdySession* spdy_session); // Creates a Value summary of the state of the spdy session pool. - scoped_ptr<base::Value> SpdySessionPoolInfoToValue() const; + std::unique_ptr<base::Value> SpdySessionPoolInfoToValue() const; base::WeakPtr<HttpServerProperties> http_server_properties() { return http_server_properties_; diff --git a/chromium/net/spdy/spdy_session_pool_unittest.cc b/chromium/net/spdy/spdy_session_pool_unittest.cc index 4d34869fcf5..1f339737bcc 100644 --- a/chromium/net/spdy/spdy_session_pool_unittest.cc +++ b/chromium/net/spdy/spdy_session_pool_unittest.cc @@ -5,11 +5,11 @@ #include "net/spdy/spdy_session_pool.h" #include <cstddef> +#include <memory> #include <string> #include <utility> #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "net/dns/host_cache.h" #include "net/http/http_network_session.h" #include "net/socket/client_socket_handle.h" @@ -43,7 +43,7 @@ class SpdySessionPoolTest : public ::testing::Test, void RunIPPoolingTest(SpdyPoolCloseSessionsType close_sessions_type); SpdySessionDependencies session_deps_; - scoped_ptr<HttpNetworkSession> http_session_; + std::unique_ptr<HttpNetworkSession> http_session_; SpdySessionPool* spdy_session_pool_; }; @@ -69,7 +69,7 @@ class SessionOpeningDelegate : public SpdyStream::Delegate { return RESPONSE_HEADERS_ARE_COMPLETE; } - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override {} + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {} void OnDataSent() override {} @@ -526,7 +526,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) { MockRead reads[] = { MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util.ConstructSpdyGet("http://www.a.com", 1, MEDIUM)); MockWrite writes[] = {CreateMockWrite(*req, 1)}; @@ -554,7 +554,7 @@ TEST_P(SpdySessionPoolTest, IPAddressChanged) { test::StreamDelegateDoNothing delegateA(spdy_streamA); spdy_streamA->SetDelegate(&delegateA); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util.ConstructGetHeaderBlock(urlA.spec())); spdy_streamA->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_streamA->HasUrlFromHeaders()); diff --git a/chromium/net/spdy/spdy_session_unittest.cc b/chromium/net/spdy/spdy_session_unittest.cc index 0cd890f6672..dae8a5f4e3b 100644 --- a/chromium/net/spdy/spdy_session_unittest.cc +++ b/chromium/net/spdy/spdy_session_unittest.cc @@ -4,12 +4,12 @@ #include "net/spdy/spdy_session.h" +#include <memory> #include <utility> #include "base/base64.h" #include "base/bind.h" #include "base/callback.h" -#include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "base/test/histogram_tester.h" #include "net/base/host_port_pair.h" @@ -135,8 +135,8 @@ class SpdySessionTest : public PlatformTest, session_deps_(GetProtocol()), spdy_session_pool_(nullptr), test_url_(kDefaultURL), - test_host_port_pair_(HostPortPair::FromURL(test_url_)), - key_(test_host_port_pair_, + test_server_(test_url_), + key_(HostPortPair::FromURL(test_url_), ProxyServer::Direct(), PRIVACY_MODE_DISABLED) { session_deps_.enable_priority_dependencies = GetDependenciesFromPriority(); @@ -206,11 +206,11 @@ class SpdySessionTest : public PlatformTest, SpdyTestUtil spdy_util_; SpdySessionDependencies session_deps_; - scoped_ptr<HttpNetworkSession> http_session_; + std::unique_ptr<HttpNetworkSession> http_session_; base::WeakPtr<SpdySession> session_; SpdySessionPool* spdy_session_pool_; GURL test_url_; - HostPortPair test_host_port_pair_; + url::SchemeHostPort test_server_; SpdySessionKey key_; BoundTestNetLog log_; }; @@ -244,7 +244,7 @@ class StreamRequestDestroyingCallback : public TestCompletionCallbackBase { ~StreamRequestDestroyingCallback() override {} - void SetRequestToDestroy(scoped_ptr<SpdyStreamRequest> request) { + void SetRequestToDestroy(std::unique_ptr<SpdyStreamRequest> request) { request_ = std::move(request); } @@ -259,7 +259,7 @@ class StreamRequestDestroyingCallback : public TestCompletionCallbackBase { SetResult(result); } - scoped_ptr<SpdyStreamRequest> request_; + std::unique_ptr<SpdyStreamRequest> request_; }; } // namespace @@ -287,7 +287,7 @@ TEST_P(SpdySessionTest, PendingStreamCancellingAnother) { } SpdyStreamRequest request1; - scoped_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest); + std::unique_ptr<SpdyStreamRequest> request2(new SpdyStreamRequest); StreamRequestDestroyingCallback callback1; ASSERT_EQ( @@ -312,7 +312,8 @@ TEST_P(SpdySessionTest, PendingStreamCancellingAnother) { TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); MockRead reads[] = { CreateMockRead(*goaway, 0), }; @@ -337,7 +338,8 @@ TEST_P(SpdySessionTest, GoAwayWithNoActiveStreams) { TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); MockRead reads[] = { CreateMockRead(*goaway, 0, SYNCHRONOUS), MockRead(ASYNC, 0, 1) // EOF }; @@ -360,16 +362,17 @@ TEST_P(SpdySessionTest, GoAwayImmediatelyWithNoActiveStreams) { TEST_P(SpdySessionTest, GoAwayWithActiveStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*goaway, 3), MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF }; - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -393,9 +396,9 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) { test::StreamDelegateDoNothing delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); + std::unique_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -435,13 +438,14 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreams) { TEST_P(SpdySessionTest, GoAwayWithActiveAndCreatedStream) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(0)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(0)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*goaway, 2), }; // No |req2|, because the second stream will never get activated. - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -458,7 +462,7 @@ TEST_P(SpdySessionTest, GoAwayWithActiveAndCreatedStream) { SPDY_REQUEST_RESPONSE_STREAM, session_, test_url_, MEDIUM, BoundNetLog()); test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -493,8 +497,10 @@ TEST_P(SpdySessionTest, GoAwayWithActiveAndCreatedStream) { TEST_P(SpdySessionTest, GoAwayTwice) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway1(spdy_util_.ConstructSpdyGoAway(1)); - scoped_ptr<SpdySerializedFrame> goaway2(spdy_util_.ConstructSpdyGoAway(0)); + std::unique_ptr<SpdySerializedFrame> goaway1( + spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway2( + spdy_util_.ConstructSpdyGoAway(0)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*goaway1, 3), @@ -503,9 +509,9 @@ TEST_P(SpdySessionTest, GoAwayTwice) { MockRead(ASYNC, ERR_IO_PENDING, 6), MockRead(ASYNC, 0, 7) // EOF }; - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -529,9 +535,9 @@ TEST_P(SpdySessionTest, GoAwayTwice) { test::StreamDelegateDoNothing delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); + std::unique_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -569,16 +575,17 @@ TEST_P(SpdySessionTest, GoAwayTwice) { TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 2), CreateMockRead(*goaway, 3), MockRead(ASYNC, ERR_IO_PENDING, 4), MockRead(ASYNC, 0, 5) // EOF }; - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -602,9 +609,9 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { test::StreamDelegateDoNothing delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); - scoped_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); + std::unique_ptr<SpdyHeaderBlock> headers2(new SpdyHeaderBlock(*headers)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -643,21 +650,22 @@ TEST_P(SpdySessionTest, GoAwayWithActiveStreamsThenClose) { TEST_P(SpdySessionTest, GoAwayWhileDraining) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); size_t joint_size = goaway->size() * 2 + body->size(); // Compose interleaved |goaway| and |body| frames into a single read. - scoped_ptr<char[]> buffer(new char[joint_size]); + std::unique_ptr<char[]> buffer(new char[joint_size]); { size_t out = 0; memcpy(&buffer[out], goaway->data(), goaway->size()); @@ -686,7 +694,7 @@ TEST_P(SpdySessionTest, GoAwayWhileDraining) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -705,14 +713,15 @@ TEST_P(SpdySessionTest, GoAwayWhileDraining) { TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), CreateMockRead(*goaway, 2), MockRead(ASYNC, ERR_IO_PENDING, 3), MockRead(ASYNC, 0, 4) // EOF }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -730,7 +739,7 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -765,8 +774,9 @@ TEST_P(SpdySessionTest, CreateStreamAfterGoAway) { TEST_P(SpdySessionTest, SynStreamAfterGoAway) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway(1)); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> goaway( + spdy_util_.ConstructSpdyGoAway(1)); + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kDefaultURL)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -775,9 +785,9 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) { CreateMockRead(*push, 4), MockRead(ASYNC, 0, 6) // EOF }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)}; SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); @@ -793,7 +803,7 @@ TEST_P(SpdySessionTest, SynStreamAfterGoAway) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -826,7 +836,7 @@ TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF }; - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -844,7 +854,7 @@ TEST_P(SpdySessionTest, NetworkChangeWithActiveStreams) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); @@ -885,14 +895,14 @@ TEST_P(SpdySessionTest, ClientPing) { session_deps_.enable_ping = true; session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> read_ping( + std::unique_ptr<SpdySerializedFrame> read_ping( spdy_util_.ConstructSpdyPing(1, true)); MockRead reads[] = { CreateMockRead(*read_ping, 1), MockRead(ASYNC, ERR_IO_PENDING, 2), MockRead(ASYNC, 0, 3) // EOF }; - scoped_ptr<SpdySerializedFrame> write_ping( + std::unique_ptr<SpdySerializedFrame> write_ping( spdy_util_.ConstructSpdyPing(1, false)); MockWrite writes[] = { CreateMockWrite(*write_ping, 0), @@ -938,13 +948,13 @@ TEST_P(SpdySessionTest, ClientPing) { TEST_P(SpdySessionTest, ServerPing) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> read_ping( + std::unique_ptr<SpdySerializedFrame> read_ping( spdy_util_.ConstructSpdyPing(2, false)); MockRead reads[] = { CreateMockRead(*read_ping), MockRead(SYNCHRONOUS, 0, 0) // EOF }; - scoped_ptr<SpdySerializedFrame> write_ping( + std::unique_ptr<SpdySerializedFrame> write_ping( spdy_util_.ConstructSpdyPing(2, true)); MockWrite writes[] = { CreateMockWrite(*write_ping), @@ -979,9 +989,9 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) { session_deps_.enable_ping = true; session_deps_.time_func = TheNearFuture; - scoped_ptr<SpdySerializedFrame> write_ping( + std::unique_ptr<SpdySerializedFrame> write_ping( spdy_util_.ConstructSpdyPing(1, false)); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -1005,7 +1015,7 @@ TEST_P(SpdySessionTest, PingAndWriteLoop) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); @@ -1031,23 +1041,23 @@ TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { // stalled streams are aborted. Also verify the activated streams complete, // at which point the session closes. - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId - 2, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, kLastStreamId, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), CreateMockWrite(*req2, 1), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId - 2)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, kLastStreamId)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(kLastStreamId - 2, true)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(kLastStreamId, true)); MockRead reads[] = { @@ -1100,7 +1110,7 @@ TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { // Activate stream 1. One ID remains available. stream1->SendRequestHeaders( - scoped_ptr<SpdyHeaderBlock>( + std::unique_ptr<SpdyHeaderBlock>( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)), NO_MORE_DATA_TO_SEND); base::RunLoop().RunUntilIdle(); @@ -1112,7 +1122,7 @@ TEST_P(SpdySessionTest, StreamIdSpaceExhausted) { // Activate stream 2. ID space is exhausted. stream2->SendRequestHeaders( - scoped_ptr<SpdyHeaderBlock>( + std::unique_ptr<SpdyHeaderBlock>( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)), NO_MORE_DATA_TO_SEND); base::RunLoop().RunUntilIdle(); @@ -1151,13 +1161,13 @@ TEST_P(SpdySessionTest, MaxConcurrentStreamsZero) { SettingsMap settings_zero; settings_zero[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 0); - scoped_ptr<SpdySerializedFrame> settings_frame_zero( + std::unique_ptr<SpdySerializedFrame> settings_frame_zero( spdy_util_.ConstructSpdySettings(settings_zero)); reads.push_back(CreateMockRead(*settings_frame_zero, seq++)); // Acknowledge it. std::vector<MockWrite> writes; - scoped_ptr<SpdySerializedFrame> settings_ack0; + std::unique_ptr<SpdySerializedFrame> settings_ack0; if (GetProtocol() == kProtoHTTP2) { settings_ack0.reset(spdy_util_.ConstructSpdySettingsAck()); writes.push_back(CreateMockWrite(*settings_ack0, seq++)); @@ -1170,27 +1180,27 @@ TEST_P(SpdySessionTest, MaxConcurrentStreamsZero) { SettingsMap settings_one; settings_one[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 1); - scoped_ptr<SpdySerializedFrame> settings_frame_one( + std::unique_ptr<SpdySerializedFrame> settings_frame_one( spdy_util_.ConstructSpdySettings(settings_one)); reads.push_back(CreateMockRead(*settings_frame_one, seq++)); // Acknowledge it. - scoped_ptr<SpdySerializedFrame> settings_ack1; + std::unique_ptr<SpdySerializedFrame> settings_ack1; if (GetProtocol() == kProtoHTTP2) { settings_ack1.reset(spdy_util_.ConstructSpdySettingsAck()); writes.push_back(CreateMockWrite(*settings_ack1, seq++)); } // Request and response. - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); writes.push_back(CreateMockWrite(*req, seq++)); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); reads.push_back(CreateMockRead(*resp, seq++)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); reads.push_back(CreateMockRead(*body, seq++)); @@ -1235,7 +1245,7 @@ TEST_P(SpdySessionTest, MaxConcurrentStreamsZero) { base::WeakPtr<SpdyStream> stream = request.ReleaseStream(); test::StreamDelegateDoNothing delegate(stream); stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(stream->HasUrlFromHeaders()); @@ -1313,19 +1323,19 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { session_deps_.host_resolver->set_synchronous_mode(true); session_deps_.time_func = TheNearFuture; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = {CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5)}; - scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, "http://www.example.org/a.dat")); - scoped_ptr<SpdySerializedFrame> push_a_body( + std::unique_ptr<SpdySerializedFrame> push_a_body( spdy_util_.ConstructSpdyBodyFrame(2, false)); // In ascii "0" < "a". We use it to verify that we properly handle std::map // iterators inside. See http://crbug.com/443490 - scoped_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush( nullptr, 0, 4, 1, "http://www.example.org/0.dat")); MockRead reads[] = { CreateMockRead(*push_a, 1), @@ -1348,7 +1358,7 @@ TEST_P(SpdySessionTest, DeleteExpiredPushStreams) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); @@ -1394,9 +1404,9 @@ TEST_P(SpdySessionTest, FailedPing) { MockRead reads[] = { MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. }; - scoped_ptr<SpdySerializedFrame> write_ping( + std::unique_ptr<SpdySerializedFrame> write_ping( spdy_util_.ConstructSpdyPing(1, false)); - scoped_ptr<SpdySerializedFrame> goaway( + std::unique_ptr<SpdySerializedFrame> goaway( spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Failed ping.")); MockWrite writes[] = {CreateMockWrite(*write_ping), CreateMockWrite(*goaway)}; @@ -1452,7 +1462,7 @@ TEST_P(SpdySessionTest, OnSettings) { int seq = 0; std::vector<MockWrite> writes; - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); if (GetProtocol() == kProtoHTTP2) { writes.push_back(CreateMockWrite(*settings_ack, ++seq)); @@ -1462,7 +1472,7 @@ TEST_P(SpdySessionTest, OnSettings) { const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1; new_settings[kSpdySettingsIds] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); MockRead reads[] = { CreateMockRead(*settings_frame, 0), @@ -1519,7 +1529,7 @@ TEST_P(SpdySessionTest, ClearSettings) { const uint32_t max_concurrent_streams = kInitialMaxConcurrentStreams + 1; new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); uint8_t flags = SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; test::SetFrameFlags(settings_frame.get(), flags, spdy_util_.spdy_version()); @@ -1536,14 +1546,12 @@ TEST_P(SpdySessionTest, ClearSettings) { // Initialize the SpdySetting with the default. spdy_session_pool_->http_server_properties()->SetSpdySetting( - test_host_port_pair_, - SETTINGS_MAX_CONCURRENT_STREAMS, - SETTINGS_FLAG_PLEASE_PERSIST, - kInitialMaxConcurrentStreams); + test_server_, SETTINGS_MAX_CONCURRENT_STREAMS, + SETTINGS_FLAG_PLEASE_PERSIST, kInitialMaxConcurrentStreams); - EXPECT_FALSE( - spdy_session_pool_->http_server_properties()->GetSpdySettings( - test_host_port_pair_).empty()); + EXPECT_FALSE(spdy_session_pool_->http_server_properties() + ->GetSpdySettings(test_server_) + .empty()); CreateInsecureSpdySession(); @@ -1567,9 +1575,9 @@ TEST_P(SpdySessionTest, ClearSettings) { EXPECT_EQ(OK, stream_releaser.WaitForResult()); // Make sure that persisted data is cleared. - EXPECT_TRUE( - spdy_session_pool_->http_server_properties()->GetSpdySettings( - test_host_port_pair_).empty()); + EXPECT_TRUE(spdy_session_pool_->http_server_properties() + ->GetSpdySettings(test_server_) + .empty()); // Make sure session's max_concurrent_streams is correct. EXPECT_EQ(kInitialMaxConcurrentStreams + 1, @@ -1599,10 +1607,8 @@ TEST_P(SpdySessionTest, CancelPendingCreateStream) { // Initialize the SpdySetting with 1 max concurrent streams. spdy_session_pool_->http_server_properties()->SetSpdySetting( - test_host_port_pair_, - SETTINGS_MAX_CONCURRENT_STREAMS, - SETTINGS_FLAG_PLEASE_PERSIST, - 1); + test_server_, SETTINGS_MAX_CONCURRENT_STREAMS, + SETTINGS_FLAG_PLEASE_PERSIST, 1); CreateInsecureSpdySession(); @@ -1620,7 +1626,7 @@ TEST_P(SpdySessionTest, CancelPendingCreateStream) { // Use scoped_ptr to let us invalidate the memory when we want to, to trigger // a valgrind error if the callback is invoked when it's not supposed to be. - scoped_ptr<TestCompletionCallback> callback(new TestCompletionCallback); + std::unique_ptr<TestCompletionCallback> callback(new TestCompletionCallback); SpdyStreamRequest request; ASSERT_EQ(ERR_IO_PENDING, @@ -1648,7 +1654,7 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { SettingsMap settings; settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, kMaxConcurrentPushedStreams); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(settings)); std::vector<MockWrite> writes; if (GetProtocol() == kProtoHTTP2) { @@ -1664,7 +1670,7 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { server_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_PERSISTED, initial_max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> server_settings_frame( + std::unique_ptr<SpdySerializedFrame> server_settings_frame( spdy_util_.ConstructSpdySettings(server_settings)); if (GetProtocol() == kProtoSPDY31) { writes.push_back(CreateMockWrite(*server_settings_frame)); @@ -1677,10 +1683,8 @@ TEST_P(SpdySessionTest, SendInitialDataOnNewSession) { CreateNetworkSession(); spdy_session_pool_->http_server_properties()->SetSpdySetting( - test_host_port_pair_, - SETTINGS_MAX_CONCURRENT_STREAMS, - SETTINGS_FLAG_PLEASE_PERSIST, - initial_max_concurrent_streams); + test_server_, SETTINGS_MAX_CONCURRENT_STREAMS, + SETTINGS_FLAG_PLEASE_PERSIST, initial_max_concurrent_streams); SpdySessionPoolPeer pool_peer(spdy_session_pool_); pool_peer.SetEnableSendingInitialData(true); @@ -1697,16 +1701,14 @@ TEST_P(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { base::WeakPtr<HttpServerProperties> test_http_server_properties = spdy_session_pool_->http_server_properties(); SettingsFlagsAndValue flags_and_value1(SETTINGS_FLAG_PLEASE_PERSIST, 2); - test_http_server_properties->SetSpdySetting( - test_host_port_pair_, - SETTINGS_MAX_CONCURRENT_STREAMS, - SETTINGS_FLAG_PLEASE_PERSIST, - 2); - EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( - test_host_port_pair_).size()); + test_http_server_properties->SetSpdySetting(test_server_, + SETTINGS_MAX_CONCURRENT_STREAMS, + SETTINGS_FLAG_PLEASE_PERSIST, 2); + EXPECT_NE(0u, + test_http_server_properties->GetSpdySettings(test_server_).size()); spdy_session_pool_->OnIPAddressChanged(); - EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( - test_host_port_pair_).size()); + EXPECT_EQ(0u, + test_http_server_properties->GetSpdySettings(test_server_).size()); } TEST_P(SpdySessionTest, Initialize) { @@ -1746,7 +1748,7 @@ TEST_P(SpdySessionTest, Initialize) { TEST_P(SpdySessionTest, NetLogOnSessionGoaway) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway( + std::unique_ptr<SpdySerializedFrame> goaway( spdy_util_.ConstructSpdyGoAway(42, GOAWAY_ENHANCE_YOUR_CALM, "foo")); MockRead reads[] = { CreateMockRead(*goaway), @@ -1842,7 +1844,7 @@ TEST_P(SpdySessionTest, NetLogOnSessionEOF) { } TEST_P(SpdySessionTest, SynCompressionHistograms) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), @@ -1861,7 +1863,7 @@ TEST_P(SpdySessionTest, SynCompressionHistograms) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -1896,22 +1898,22 @@ TEST_P(SpdySessionTest, SynCompressionHistograms) { // first. TEST_P(SpdySessionTest, OutOfOrderSynStreams) { // Construct the request. - scoped_ptr<SpdySerializedFrame> req_highest( + std::unique_ptr<SpdySerializedFrame> req_highest( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, HIGHEST, true)); - scoped_ptr<SpdySerializedFrame> req_lowest( + std::unique_ptr<SpdySerializedFrame> req_lowest( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req_highest, 0), CreateMockWrite(*req_lowest, 1), }; - scoped_ptr<SpdySerializedFrame> resp_highest( + std::unique_ptr<SpdySerializedFrame> resp_highest( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body_highest( + std::unique_ptr<SpdySerializedFrame> body_highest( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> resp_lowest( + std::unique_ptr<SpdySerializedFrame> resp_lowest( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); - scoped_ptr<SpdySerializedFrame> body_lowest( + std::unique_ptr<SpdySerializedFrame> body_lowest( spdy_util_.ConstructSpdyBodyFrame(3, true)); MockRead reads[] = { CreateMockRead(*resp_highest, 2), @@ -1946,13 +1948,13 @@ TEST_P(SpdySessionTest, OutOfOrderSynStreams) { // Queue the lower priority one first. - scoped_ptr<SpdyHeaderBlock> headers_lowest( + std::unique_ptr<SpdyHeaderBlock> headers_lowest( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream_lowest->SendRequestHeaders(std::move(headers_lowest), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream_lowest->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers_highest( + std::unique_ptr<SpdyHeaderBlock> headers_highest( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream_highest->SendRequestHeaders(std::move(headers_highest), NO_MORE_DATA_TO_SEND); @@ -1969,15 +1971,15 @@ TEST_P(SpdySessionTest, OutOfOrderSynStreams) { TEST_P(SpdySessionTest, CancelStream) { // Request 1, at HIGHEST priority, will be cancelled before it writes data. // Request 2, at LOWEST priority, will be a full request and will be id 1. - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*req2, 0), }; - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { CreateMockRead(*resp2, 1), @@ -2009,12 +2011,12 @@ TEST_P(SpdySessionTest, CancelStream) { test::StreamDelegateDoNothing delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); @@ -2072,12 +2074,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedSelfClosingStreams) { test::ClosingDelegate delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); @@ -2128,12 +2130,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { test::ClosingDelegate delegate2(spdy_stream1); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); @@ -2160,9 +2162,9 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoCreatedMutuallyClosingStreams) { TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -2195,12 +2197,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { test::ClosingDelegate delegate2(spdy_stream2); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); @@ -2234,9 +2236,9 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedSelfClosingStreams) { TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -2271,12 +2273,12 @@ TEST_P(SpdySessionTest, CloseSessionWithTwoActivatedMutuallyClosingStreams) { test::ClosingDelegate delegate2(spdy_stream1); spdy_stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream2->HasUrlFromHeaders()); @@ -2328,11 +2330,11 @@ class SessionClosingDelegate : public test::StreamDelegateDoNothing { TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); - scoped_ptr<SpdySerializedFrame> goaway( + std::unique_ptr<SpdySerializedFrame> goaway( spdy_util_.ConstructSpdyGoAway(0, GOAWAY_PROTOCOL_ERROR, "Error")); // The GOAWAY has higher-priority than the RST_STREAM, and is written first // despite being queued second. @@ -2359,7 +2361,7 @@ TEST_P(SpdySessionTest, CloseActivatedStreamThatClosesSession) { SessionClosingDelegate delegate(spdy_stream, session_); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -2451,15 +2453,15 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { new_settings[kSpdySettingsIds1] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, max_concurrent_streams); - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); spdy_util_.UpdateWithStreamDestruction(1); - scoped_ptr<SpdySerializedFrame> req2( + std::unique_ptr<SpdySerializedFrame> req2( spdy_util_.ConstructSpdyGet(nullptr, 0, 3, LOWEST, true)); spdy_util_.UpdateWithStreamDestruction(3); - scoped_ptr<SpdySerializedFrame> req3( + std::unique_ptr<SpdySerializedFrame> req3( spdy_util_.ConstructSpdyGet(nullptr, 0, 5, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*settings_ack, 1), @@ -2470,22 +2472,22 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { // Set up the socket so we read a SETTINGS frame that sets max concurrent // streams to 1. - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, true)); - scoped_ptr<SpdySerializedFrame> resp3( + std::unique_ptr<SpdySerializedFrame> resp3( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 5)); - scoped_ptr<SpdySerializedFrame> body3( + std::unique_ptr<SpdySerializedFrame> body3( spdy_util_.ConstructSpdyBodyFrame(5, true)); MockRead reads[] = { @@ -2534,7 +2536,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { EXPECT_EQ(1u, session_->num_created_streams()); EXPECT_EQ(2u, session_->pending_create_stream_queue_size(LOWEST)); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -2559,7 +2561,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { base::WeakPtr<SpdyStream> stream2 = request2.ReleaseStream(); test::StreamDelegateDoNothing delegate2(stream2); stream2->SetDelegate(&delegate2); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); stream2->SendRequestHeaders(std::move(headers2), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(stream2->HasUrlFromHeaders()); @@ -2584,7 +2586,7 @@ TEST_P(SpdySessionTest, CloseTwoStalledCreateStream) { base::WeakPtr<SpdyStream> stream3 = request3.ReleaseStream(); test::StreamDelegateDoNothing delegate3(stream3); stream3->SetDelegate(&delegate3); - scoped_ptr<SpdyHeaderBlock> headers3( + std::unique_ptr<SpdyHeaderBlock> headers3( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); stream3->SendRequestHeaders(std::move(headers3), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(stream3->HasUrlFromHeaders()); @@ -2683,7 +2685,7 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -2699,12 +2701,12 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) { char* payload_data = payload->data(); test_stream.GetBytes(payload_data, kPayloadSize); - scoped_ptr<SpdySerializedFrame> partial_data_frame( + std::unique_ptr<SpdySerializedFrame> partial_data_frame( framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> finish_data_frame( + std::unique_ptr<SpdySerializedFrame> finish_data_frame( framer.CreateDataFrame(1, payload_data, kPayloadSize - 1, DATA_FLAG_FIN)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); // Write 1 byte less than kMaxReadBytes to check that DoRead reads up to 32k @@ -2733,7 +2735,7 @@ TEST_P(SpdySessionTest, ReadDataWithoutYielding) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -2770,13 +2772,13 @@ TEST_P(SpdySessionTest, TestYieldingSlowReads) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); MockRead reads[] = { @@ -2797,7 +2799,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowReads) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -2831,18 +2833,18 @@ TEST_P(SpdySessionTest, TestYieldingSlowSynchronousReads) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), }; - scoped_ptr<SpdySerializedFrame> partial_data_frame( + std::unique_ptr<SpdySerializedFrame> partial_data_frame( framer.CreateDataFrame(1, "foo ", 4, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> finish_data_frame( + std::unique_ptr<SpdySerializedFrame> finish_data_frame( framer.CreateDataFrame(1, "bar", 3, DATA_FLAG_FIN)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); MockRead reads[] = { @@ -2868,7 +2870,7 @@ TEST_P(SpdySessionTest, TestYieldingSlowSynchronousReads) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -2899,7 +2901,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -2915,12 +2917,12 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) { char* payload_data = payload->data(); test_stream.GetBytes(payload_data, kPayloadSize); - scoped_ptr<SpdySerializedFrame> partial_data_frame( + std::unique_ptr<SpdySerializedFrame> partial_data_frame( framer.CreateDataFrame(1, payload_data, kPayloadSize, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> finish_data_frame( + std::unique_ptr<SpdySerializedFrame> finish_data_frame( framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); // Write 1 byte more than kMaxReadBytes to check that DoRead yields. @@ -2949,7 +2951,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringReadData) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -2993,7 +2995,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -3016,14 +3018,14 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { char* twok_payload_data = twok_payload->data(); test_stream2.GetBytes(twok_payload_data, kTwoKPayloadSize); - scoped_ptr<SpdySerializedFrame> eightk_data_frame(framer.CreateDataFrame( + std::unique_ptr<SpdySerializedFrame> eightk_data_frame(framer.CreateDataFrame( 1, eightk_payload_data, kEightKPayloadSize, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> twok_data_frame(framer.CreateDataFrame( + std::unique_ptr<SpdySerializedFrame> twok_data_frame(framer.CreateDataFrame( 1, twok_payload_data, kTwoKPayloadSize, DATA_FLAG_NONE)); - scoped_ptr<SpdySerializedFrame> finish_data_frame( + std::unique_ptr<SpdySerializedFrame> finish_data_frame( framer.CreateDataFrame(1, "h", 1, DATA_FLAG_FIN)); - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); MockRead reads[] = { @@ -3056,7 +3058,7 @@ TEST_P(SpdySessionTest, TestYieldingDuringAsyncReadData) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -3092,17 +3094,17 @@ TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { BufferedSpdyFramer framer(spdy_util_.spdy_version()); - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway()); + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway()); MockRead reads[] = { CreateMockRead(*resp1, 1), @@ -3125,7 +3127,7 @@ TEST_P(SpdySessionTest, GoAwayWhileInDoReadLoop) { ASSERT_TRUE(spdy_stream1.get() != nullptr); EXPECT_EQ(0u, spdy_stream1->stream_id()); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers1), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -3201,7 +3203,7 @@ TEST_P(SpdySessionTest, CloseOneIdleConnection) { scoped_refptr<TransportSocketParams> params2(new TransportSocketParams( host_port2, false, OnHostResolutionCallback(), TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); - scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); + std::unique_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED, @@ -3276,7 +3278,7 @@ TEST_P(SpdySessionTest, CloseOneIdleConnectionWithAlias) { scoped_refptr<TransportSocketParams> params3(new TransportSocketParams( host_port3, false, OnHostResolutionCallback(), TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); - scoped_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); + std::unique_ptr<ClientSocketHandle> connection3(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection3->Init(host_port3.ToString(), params3, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED, @@ -3302,9 +3304,9 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { MockRead reads[] = { MockRead(SYNCHRONOUS, ERR_IO_PENDING) // Stall forever. }; - scoped_ptr<SpdySerializedFrame> req1( + std::unique_ptr<SpdySerializedFrame> req1( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> cancel1( + std::unique_ptr<SpdySerializedFrame> cancel1( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*req1, 1), @@ -3342,7 +3344,7 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { test::StreamDelegateDoNothing delegate1(spdy_stream1); spdy_stream1->SetDelegate(&delegate1); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); EXPECT_EQ(ERR_IO_PENDING, spdy_stream1->SendRequestHeaders( std::move(headers1), NO_MORE_DATA_TO_SEND)); @@ -3357,7 +3359,7 @@ TEST_P(SpdySessionTest, CloseSessionOnIdleWhenPoolStalled) { scoped_refptr<TransportSocketParams> params2(new TransportSocketParams( host_port2, false, OnHostResolutionCallback(), TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); - scoped_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); + std::unique_ptr<ClientSocketHandle> connection2(new ClientSocketHandle); EXPECT_EQ(ERR_IO_PENDING, connection2->Init(host_port2.ToString(), params2, DEFAULT_PRIORITY, ClientSocketPool::RespectLimits::ENABLED, @@ -3444,13 +3446,13 @@ class StreamCreatingDelegate : public test::StreamDelegateDoNothing { TEST_P(SpdySessionTest, CreateStreamOnStreamReset) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, MEDIUM, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_REFUSED_STREAM)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -3472,7 +3474,7 @@ TEST_P(SpdySessionTest, CreateStreamOnStreamReset) { StreamCreatingDelegate delegate(spdy_stream, session_); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -3508,7 +3510,7 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { // Set up the socket so we read a SETTINGS frame that sets // INITIAL_WINDOW_SIZE. - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); MockRead reads[] = { CreateMockRead(*settings_frame, 0), @@ -3516,7 +3518,7 @@ TEST_P(SpdySessionTest, UpdateStreamsSendWindowSize) { MockRead(ASYNC, 0, 2) // EOF }; - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); MockWrite writes[] = { CreateMockWrite(*settings_ack, 3), @@ -3571,7 +3573,7 @@ TEST_P(SpdySessionTest, AdjustRecvWindowSize) { MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), MockRead(ASYNC, 0, 2) // EOF }; - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate( kSessionFlowControlStreamId, initial_window_size + delta_window_size)); @@ -3649,7 +3651,7 @@ TEST_P(SpdySessionTest, AdjustSendWindowSize) { TEST_P(SpdySessionTest, SessionFlowControlInactiveStream) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyBodyFrame(1, false)); MockRead reads[] = { CreateMockRead(*resp, 0), @@ -3688,7 +3690,7 @@ TEST_P(SpdySessionTest, SessionFlowControlPadding) { session_deps_.host_resolver->set_synchronous_mode(true); const int padding_length = 42; - scoped_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> resp(spdy_util_.ConstructSpdyBodyFrame( 1, kUploadData, kUploadDataSize, false, padding_length)); MockRead reads[] = { CreateMockRead(*resp, 0), @@ -3722,19 +3724,20 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) { const int32_t stream_max_recv_window_size = 1024; const int32_t data_frame_size = 2 * stream_max_recv_window_size; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 4), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); const std::string payload(data_frame_size, 'a'); - scoped_ptr<SpdySerializedFrame> data_frame(spdy_util_.ConstructSpdyBodyFrame( - 1, payload.data(), data_frame_size, false)); + std::unique_ptr<SpdySerializedFrame> data_frame( + spdy_util_.ConstructSpdyBodyFrame(1, payload.data(), data_frame_size, + false)); MockRead reads[] = { CreateMockRead(*resp, 1), MockRead(ASYNC, ERR_IO_PENDING, 2), @@ -3758,7 +3761,7 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchData) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -3797,7 +3800,7 @@ TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_FLOW_CONTROL_ERROR, "delta_window_size is 400 in DecreaseRecvWindowSize, which is larger " "than the receive window size of 500")); @@ -3806,10 +3809,10 @@ TEST_P(SpdySessionTest, SessionFlowControlTooMuchDataTwoDataFrames) { }; const std::string first_data_frame(first_data_frame_size, 'a'); - scoped_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame( 1, first_data_frame.data(), first_data_frame_size, false)); const std::string second_data_frame(second_data_frame_size, 'b'); - scoped_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame( 1, second_data_frame.data(), second_data_frame_size, false)); MockRead reads[] = { CreateMockRead(*first, 0), @@ -3856,21 +3859,21 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { ASSERT_LT(stream_max_recv_window_size, first_data_frame_size + second_data_frame_size); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 6), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); const std::string first_data_frame(first_data_frame_size, 'a'); - scoped_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> first(spdy_util_.ConstructSpdyBodyFrame( 1, first_data_frame.data(), first_data_frame_size, false)); const std::string second_data_frame(second_data_frame_size, 'b'); - scoped_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> second(spdy_util_.ConstructSpdyBodyFrame( 1, second_data_frame.data(), second_data_frame_size, false)); MockRead reads[] = { CreateMockRead(*resp, 1), @@ -3896,7 +3899,7 @@ TEST_P(SpdySessionTest, StreamFlowControlTooMuchDataTwoDataFrames) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); EXPECT_EQ(ERR_IO_PENDING, spdy_stream->SendRequestHeaders( std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -3940,7 +3943,7 @@ class DropReceivedDataDelegate : public test::StreamDelegateSendImmediate { ~DropReceivedDataDelegate() override {} // Drop any received data. - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override {} + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override {} }; // Send data back and forth but use a delegate that drops its received @@ -3950,20 +3953,20 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { const int32_t kMsgDataSize = 100; const std::string msg_data(kMsgDataSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame( 1, msg_data.data(), kMsgDataSize, false)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*msg, 2), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame( 1, msg_data.data(), kMsgDataSize, false)); - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate(kSessionFlowControlStreamId, kMsgDataSize)); MockRead reads[] = { @@ -3989,7 +3992,7 @@ TEST_P(SpdySessionTest, SessionFlowControlNoReceiveLeaks) { DropReceivedDataDelegate delegate(stream, msg_data); stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -4025,13 +4028,13 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { const int32_t kMsgDataSize = 100; const std::string msg_data(kMsgDataSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0)); MockWrite writes[] = { CreateMockWrite(*req, 0), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -4055,7 +4058,7 @@ TEST_P(SpdySessionTest, SessionFlowControlNoSendLeaks) { test::StreamDelegateSendImmediate delegate(stream, msg_data); stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -4098,20 +4101,20 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { const int32_t kMsgDataSize = 100; const std::string msg_data(kMsgDataSize, 'a'); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kMsgDataSize, MEDIUM, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> msg(spdy_util_.ConstructSpdyBodyFrame( 1, msg_data.data(), kMsgDataSize, false)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*msg, 2), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> echo(spdy_util_.ConstructSpdyBodyFrame( 1, msg_data.data(), kMsgDataSize, false)); - scoped_ptr<SpdySerializedFrame> window_update( + std::unique_ptr<SpdySerializedFrame> window_update( spdy_util_.ConstructSpdyWindowUpdate(kSessionFlowControlStreamId, kMsgDataSize)); MockRead reads[] = { @@ -4140,7 +4143,7 @@ TEST_P(SpdySessionTest, SessionFlowControlEndToEnd) { test::StreamDelegateSendImmediate delegate(stream, msg_data); stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kMsgDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -4208,18 +4211,18 @@ void SpdySessionTest::RunResumeAfterUnstallTest( const base::Callback<void(SpdyStream*, int32_t)>& unstall_function) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*body, 1), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> echo( + std::unique_ptr<SpdySerializedFrame> echo( spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); MockRead reads[] = { CreateMockRead(*resp, 2), MockRead(ASYNC, 0, 3) // EOF @@ -4241,7 +4244,7 @@ void SpdySessionTest::RunResumeAfterUnstallTest( EXPECT_FALSE(stream->HasUrlFromHeaders()); EXPECT_FALSE(stream->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -4326,13 +4329,13 @@ TEST_P(SpdySessionTest, StallSessionStreamResumeAfterUnstallStreamSession) { TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( kDefaultURL, 3, kBodyDataSize, MEDIUM, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, true)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -4341,9 +4344,9 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { CreateMockWrite(*body1, 3), }; - scoped_ptr<SpdySerializedFrame> resp1( + std::unique_ptr<SpdySerializedFrame> resp1( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); MockRead reads[] = { CreateMockRead(*resp1, 4), @@ -4380,7 +4383,7 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { StallSessionSend(); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1), MORE_DATA_TO_SEND)); @@ -4391,7 +4394,7 @@ TEST_P(SpdySessionTest, ResumeByPriorityAfterSendWindowSizeIncrease) { EXPECT_EQ(1u, stream1->stream_id()); EXPECT_TRUE(stream1->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2), MORE_DATA_TO_SEND)); @@ -4467,13 +4470,13 @@ class StreamClosingDelegate : public test::StreamDelegateWithBody { TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( kDefaultURL, 3, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> req3(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req3(spdy_util_.ConstructSpdyPost( kDefaultURL, 5, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> body2( + std::unique_ptr<SpdySerializedFrame> body2( spdy_util_.ConstructSpdyBodyFrame(3, kBodyData, kBodyDataSize, true)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -4482,7 +4485,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { CreateMockWrite(*body2, 3), }; - scoped_ptr<SpdySerializedFrame> resp2( + std::unique_ptr<SpdySerializedFrame> resp2( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 3)); MockRead reads[] = { CreateMockRead(*resp2, 4), @@ -4529,7 +4532,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { StallSessionSend(); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1), MORE_DATA_TO_SEND)); @@ -4540,7 +4543,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { EXPECT_EQ(1u, stream1->stream_id()); EXPECT_TRUE(stream1->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2), MORE_DATA_TO_SEND)); @@ -4551,7 +4554,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { EXPECT_EQ(3u, stream2->stream_id()); EXPECT_TRUE(stream2->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers3( + std::unique_ptr<SpdyHeaderBlock> headers3( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream3->SendRequestHeaders(std::move(headers3), MORE_DATA_TO_SEND)); @@ -4614,11 +4617,11 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedStreams) { TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { session_deps_.host_resolver->set_synchronous_mode(true); - scoped_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req1(spdy_util_.ConstructSpdyPost( kDefaultURL, 1, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req2(spdy_util_.ConstructSpdyPost( kDefaultURL, 3, kBodyDataSize, LOWEST, nullptr, 0)); - scoped_ptr<SpdySerializedFrame> body1( + std::unique_ptr<SpdySerializedFrame> body1( spdy_util_.ConstructSpdyBodyFrame(1, kBodyData, kBodyDataSize, false)); MockWrite writes[] = { CreateMockWrite(*req1, 0), @@ -4658,7 +4661,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { StallSessionSend(); - scoped_ptr<SpdyHeaderBlock> headers1( + std::unique_ptr<SpdyHeaderBlock> headers1( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream1->SendRequestHeaders(std::move(headers1), MORE_DATA_TO_SEND)); @@ -4669,7 +4672,7 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { EXPECT_EQ(1u, stream1->stream_id()); EXPECT_TRUE(stream1->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers2( + std::unique_ptr<SpdyHeaderBlock> headers2( spdy_util_.ConstructPostHeaderBlock(kDefaultURL, kBodyDataSize)); EXPECT_EQ(ERR_IO_PENDING, stream2->SendRequestHeaders(std::move(headers2), MORE_DATA_TO_SEND)); @@ -4707,9 +4710,9 @@ TEST_P(SpdySessionTest, SendWindowSizeIncreaseWithDeletedSession) { } TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( + std::unique_ptr<SpdySerializedFrame> goaway(spdy_util_.ConstructSpdyGoAway( 0, GOAWAY_FLOW_CONTROL_ERROR, "delta_window_size is 6 in DecreaseRecvWindowSize, which is larger than " "the receive window size of 1")); @@ -4717,9 +4720,9 @@ TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { CreateMockWrite(*req, 0), CreateMockWrite(*goaway, 4), }; - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(nullptr, 0, 1)); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, true)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -4739,7 +4742,7 @@ TEST_P(SpdySessionTest, GoAwayOnSessionFlowControlError) { test::StreamDelegateDoNothing delegate(spdy_stream); spdy_stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); @@ -4786,9 +4789,9 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { SettingsMap new_settings; new_settings[SETTINGS_MAX_CONCURRENT_STREAMS] = SettingsFlagsAndValue(SETTINGS_FLAG_NONE, 2); - scoped_ptr<SpdySerializedFrame> settings_frame( + std::unique_ptr<SpdySerializedFrame> settings_frame( spdy_util_.ConstructSpdySettings(new_settings)); - scoped_ptr<SpdySerializedFrame> pushed(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> pushed(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, "http://www.example.org/a.dat")); MockRead reads[] = { CreateMockRead(*settings_frame, 0), @@ -4798,9 +4801,9 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { MockRead(ASYNC, 0, 6), }; - scoped_ptr<SpdySerializedFrame> settings_ack( + std::unique_ptr<SpdySerializedFrame> settings_ack( spdy_util_.ConstructSpdySettingsAck()); - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); MockWrite writes[] = { CreateMockWrite(*settings_ack, 1), CreateMockWrite(*req, 2), @@ -4827,7 +4830,7 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -4867,9 +4870,9 @@ TEST_P(SpdySessionTest, PushedStreamShouldNotCountToClientConcurrencyLimit) { } TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { - scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, "http://www.example.org/a.dat")); - scoped_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_b(spdy_util_.ConstructSpdyPush( nullptr, 0, 4, 1, "http://www.example.org/b.dat")); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -4880,9 +4883,9 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { MockRead(ASYNC, 0, 7), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), @@ -4907,7 +4910,7 @@ TEST_P(SpdySessionTest, RejectPushedStreamExceedingConcurrencyLimit) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -4953,11 +4956,11 @@ TEST_P(SpdySessionTest, TrustedSpdyProxy) { // cross_origin_push contains HTTP resource for an origin different from the // origin of kDefaultURL, and should be accepted. - scoped_ptr<SpdySerializedFrame> cross_origin_push( + std::unique_ptr<SpdySerializedFrame> cross_origin_push( spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin)); // cross_origin_https_push contains HTTPS resource, and should be refused. - scoped_ptr<SpdySerializedFrame> cross_origin_https_push( + std::unique_ptr<SpdySerializedFrame> cross_origin_https_push( spdy_util_.ConstructSpdyPush(nullptr, 0, 4, 1, kHttpsURLFromAnotherOrigin)); MockRead reads[] = { @@ -4969,9 +4972,9 @@ TEST_P(SpdySessionTest, TrustedSpdyProxy) { MockRead(ASYNC, 0, 7), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), @@ -4980,7 +4983,7 @@ TEST_P(SpdySessionTest, TrustedSpdyProxy) { SequencedSocketData data(reads, arraysize(reads), writes, arraysize(writes)); session_deps_.socket_factory->AddSocketDataProvider(&data); - scoped_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate()); + std::unique_ptr<TestProxyDelegate> proxy_delegate(new TestProxyDelegate()); proxy_delegate->set_trusted_spdy_proxy( net::ProxyServer(net::ProxyServer::SCHEME_HTTPS, HostPortPair(GURL(kDefaultURL).host(), 80))); @@ -5001,7 +5004,7 @@ TEST_P(SpdySessionTest, TrustedSpdyProxy) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -5046,7 +5049,7 @@ TEST_P(SpdySessionTest, TrustedSpdyProxyNotSet) { // cross_origin_push contains resource for an origin different from the // origin of kDefaultURL, and should be refused. - scoped_ptr<SpdySerializedFrame> cross_origin_push( + std::unique_ptr<SpdySerializedFrame> cross_origin_push( spdy_util_.ConstructSpdyPush(nullptr, 0, 2, 1, kHttpURLFromAnotherOrigin)); MockRead reads[] = { @@ -5054,9 +5057,9 @@ TEST_P(SpdySessionTest, TrustedSpdyProxyNotSet) { MockRead(ASYNC, 0, 4), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 3), @@ -5080,7 +5083,7 @@ TEST_P(SpdySessionTest, TrustedSpdyProxyNotSet) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream->HasUrlFromHeaders()); @@ -5105,14 +5108,14 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { if (spdy_util_.spdy_version() < HTTP2) return; - scoped_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( + std::unique_ptr<SpdySerializedFrame> push_a(spdy_util_.ConstructSpdyPush( nullptr, 0, 2, 1, "http://www.example.org/a.dat")); - scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); + std::unique_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); spdy_util_.AddUrlToHeaderBlock("http://www.example.org/b.dat", push_headers.get()); - scoped_ptr<SpdySerializedFrame> push_b( + std::unique_ptr<SpdySerializedFrame> push_b( spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 4, 1)); - scoped_ptr<SpdySerializedFrame> headers_b( + std::unique_ptr<SpdySerializedFrame> headers_b( spdy_util_.ConstructSpdyPushHeaders(4, nullptr, 0)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -5125,9 +5128,9 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { MockRead(ASYNC, 0, 9), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(4, RST_STREAM_REFUSED_STREAM)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 7), @@ -5152,7 +5155,7 @@ TEST_P(SpdySessionTest, IgnoreReservedRemoteStreamsCount) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); @@ -5203,11 +5206,11 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { return; const char kPushedUrl[] = "http://www.example.org/a.dat"; - scoped_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); + std::unique_ptr<SpdyHeaderBlock> push_headers(new SpdyHeaderBlock); spdy_util_.AddUrlToHeaderBlock(kPushedUrl, push_headers.get()); - scoped_ptr<SpdySerializedFrame> push_promise( + std::unique_ptr<SpdySerializedFrame> push_promise( spdy_util_.ConstructInitialSpdyPushFrame(std::move(push_headers), 2, 1)); - scoped_ptr<SpdySerializedFrame> headers_frame( + std::unique_ptr<SpdySerializedFrame> headers_frame( spdy_util_.ConstructSpdyPushHeaders(2, nullptr, 0)); MockRead reads[] = { MockRead(ASYNC, ERR_IO_PENDING, 1), @@ -5218,9 +5221,9 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { MockRead(ASYNC, 0, 7), }; - scoped_ptr<SpdySerializedFrame> req( + std::unique_ptr<SpdySerializedFrame> req( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_CANCEL)); MockWrite writes[] = { CreateMockWrite(*req, 0), CreateMockWrite(*rst, 5), @@ -5244,7 +5247,7 @@ TEST_P(SpdySessionTest, CancelReservedStreamOnHeadersReceived) { EXPECT_EQ(0u, session_->num_pushed_streams()); EXPECT_EQ(0u, session_->num_active_pushed_streams()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kDefaultURL)); spdy_stream1->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND); EXPECT_TRUE(spdy_stream1->HasUrlFromHeaders()); diff --git a/chromium/net/spdy/spdy_stream.cc b/chromium/net/spdy/spdy_stream.cc index 9a7ddef8162..078ea22e9c3 100644 --- a/chromium/net/spdy/spdy_stream.cc +++ b/chromium/net/spdy/spdy_stream.cc @@ -14,8 +14,9 @@ #include "base/metrics/histogram_macros.h" #include "base/single_thread_task_runner.h" #include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" #include "base/strings/stringprintf.h" -#include "base/thread_task_runner_handle.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/values.h" #include "net/spdy/spdy_buffer_producer.h" #include "net/spdy/spdy_http_utils.h" @@ -25,24 +26,24 @@ namespace net { namespace { -scoped_ptr<base::Value> NetLogSpdyStreamErrorCallback( +std::unique_ptr<base::Value> NetLogSpdyStreamErrorCallback( SpdyStreamId stream_id, int status, const std::string* description, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", static_cast<int>(stream_id)); dict->SetInteger("status", status); dict->SetString("description", *description); return std::move(dict); } -scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( +std::unique_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( SpdyStreamId stream_id, int32_t delta, int32_t window_size, NetLogCaptureMode /* capture_mode */) { - scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); dict->SetInteger("stream_id", stream_id); dict->SetInteger("delta", delta); dict->SetInteger("window_size", window_size); @@ -50,12 +51,7 @@ scoped_ptr<base::Value> NetLogSpdyStreamWindowUpdateCallback( } bool ContainsUppercaseAscii(const std::string& str) { - for (std::string::const_iterator i(str.begin()); i != str.end(); ++i) { - if (*i >= 'A' && *i <= 'Z') { - return true; - } - } - return false; + return std::any_of(str.begin(), str.end(), base::IsAsciiUpper<char>); } } // namespace @@ -72,13 +68,13 @@ class SpdyStream::SynStreamBufferProducer : public SpdyBufferProducer { ~SynStreamBufferProducer() override {} - scoped_ptr<SpdyBuffer> ProduceBuffer() override { + std::unique_ptr<SpdyBuffer> ProduceBuffer() override { if (!stream_.get()) { NOTREACHED(); - return scoped_ptr<SpdyBuffer>(); + return std::unique_ptr<SpdyBuffer>(); } DCHECK_GT(stream_->stream_id(), 0u); - return scoped_ptr<SpdyBuffer>( + return std::unique_ptr<SpdyBuffer>( new SpdyBuffer(stream_->ProduceSynStreamFrame())); } @@ -181,7 +177,7 @@ void SpdyStream::PushedStreamReplay() { while (!pending_recv_data_.empty()) { // Take ownership of the first element of |pending_recv_data_|. - scoped_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0)); + std::unique_ptr<SpdyBuffer> buffer = std::move(pending_recv_data_.at(0)); pending_recv_data_.erase(pending_recv_data_.begin()); bool eof = (buffer == NULL); @@ -203,7 +199,7 @@ void SpdyStream::PushedStreamReplay() { } } -scoped_ptr<SpdySerializedFrame> SpdyStream::ProduceSynStreamFrame() { +std::unique_ptr<SpdySerializedFrame> SpdyStream::ProduceSynStreamFrame() { CHECK_EQ(io_state_, STATE_IDLE); CHECK(request_headers_); CHECK_GT(stream_id_, 0u); @@ -211,7 +207,7 @@ scoped_ptr<SpdySerializedFrame> SpdyStream::ProduceSynStreamFrame() { SpdyControlFlags flags = (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? CONTROL_FLAG_FIN : CONTROL_FLAG_NONE; - scoped_ptr<SpdySerializedFrame> frame(session_->CreateSynStream( + std::unique_ptr<SpdySerializedFrame> frame(session_->CreateSynStream( stream_id_, priority_, flags, *request_headers_)); send_time_ = base::TimeTicks::Now(); return frame; @@ -477,9 +473,13 @@ void SpdyStream::OnPushPromiseHeadersReceived(const SpdyHeaderBlock& headers) { request_headers_.reset(new SpdyHeaderBlock(headers)); } -void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +void SpdyStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { DCHECK(session_->IsStreamActive(stream_id_)); + // Track our bandwidth. + recv_bytes_ += buffer ? buffer->GetRemainingSize() : 0; + recv_last_byte_time_ = base::TimeTicks::Now(); + // If we're still buffering data for a push stream, we will do the // check for data received with incomplete headers in // PushedStreamReplayData(). @@ -541,10 +541,6 @@ void SpdyStream::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { buffer->AddConsumeCallback( base::Bind(&SpdyStream::OnReadBufferConsumed, GetWeakPtr())); - // Track our bandwidth. - recv_bytes_ += length; - recv_last_byte_time_ = base::TimeTicks::Now(); - // May close |this|. delegate_->OnDataReceived(std::move(buffer)); } @@ -576,9 +572,9 @@ void SpdyStream::OnFrameWriteComplete(SpdyFrameType frame_type, } if (pending_send_status_ == NO_MORE_DATA_TO_SEND) { - if(io_state_ == STATE_OPEN) { + if (io_state_ == STATE_OPEN) { io_state_ = STATE_HALF_CLOSED_LOCAL; - } else if(io_state_ == STATE_HALF_CLOSED_REMOTE) { + } else if (io_state_ == STATE_HALF_CLOSED_REMOTE) { io_state_ = STATE_CLOSED; } else { NOTREACHED() << io_state_; @@ -688,8 +684,9 @@ base::WeakPtr<SpdyStream> SpdyStream::GetWeakPtr() { return weak_ptr_factory_.GetWeakPtr(); } -int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, - SpdySendStatus send_status) { +int SpdyStream::SendRequestHeaders( + std::unique_ptr<SpdyHeaderBlock> request_headers, + SpdySendStatus send_status) { CHECK_NE(type_, SPDY_PUSH_STREAM); CHECK_EQ(pending_send_status_, MORE_DATA_TO_SEND); CHECK(!request_headers_); @@ -697,10 +694,9 @@ int SpdyStream::SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, CHECK_EQ(io_state_, STATE_IDLE); request_headers_ = std::move(request_headers); pending_send_status_ = send_status; - session_->EnqueueStreamWrite( - GetWeakPtr(), SYN_STREAM, - scoped_ptr<SpdyBufferProducer>( - new SynStreamBufferProducer(GetWeakPtr()))); + session_->EnqueueStreamWrite(GetWeakPtr(), SYN_STREAM, + std::unique_ptr<SpdyBufferProducer>( + new SynStreamBufferProducer(GetWeakPtr()))); return ERR_IO_PENDING; } @@ -774,8 +770,15 @@ void SpdyStream::AddRawSentBytes(size_t sent_bytes) { bool SpdyStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const { if (stream_id_ == 0) return false; - - return session_->GetLoadTimingInfo(stream_id_, load_timing_info); + bool result = session_->GetLoadTimingInfo(stream_id_, load_timing_info); + if (type_ == SPDY_PUSH_STREAM) { + load_timing_info->push_start = recv_first_byte_time_; + bool done_receiving = IsClosed() || (!pending_recv_data_.empty() && + !pending_recv_data_.back()); + if (done_receiving) + load_timing_info->push_end = recv_last_byte_time_; + } + return result; } GURL SpdyStream::GetUrlFromHeaders() const { @@ -836,11 +839,9 @@ void SpdyStream::QueueNextDataFrame() { SpdyDataFlags flags = (pending_send_status_ == NO_MORE_DATA_TO_SEND) ? DATA_FLAG_FIN : DATA_FLAG_NONE; - scoped_ptr<SpdyBuffer> data_buffer( - session_->CreateDataBuffer(stream_id_, - pending_send_data_.get(), - pending_send_data_->BytesRemaining(), - flags)); + std::unique_ptr<SpdyBuffer> data_buffer( + session_->CreateDataBuffer(stream_id_, pending_send_data_.get(), + pending_send_data_->BytesRemaining(), flags)); // We'll get called again by PossiblyResumeIfSendStalled(). if (!data_buffer) return; @@ -864,7 +865,7 @@ void SpdyStream::QueueNextDataFrame() { session_->EnqueueStreamWrite( GetWeakPtr(), DATA, - scoped_ptr<SpdyBufferProducer>( + std::unique_ptr<SpdyBufferProducer>( new SimpleBufferProducer(std::move(data_buffer)))); } diff --git a/chromium/net/spdy/spdy_stream.h b/chromium/net/spdy/spdy_stream.h index 742f24867c9..499372a9ca8 100644 --- a/chromium/net/spdy/spdy_stream.h +++ b/chromium/net/spdy/spdy_stream.h @@ -9,12 +9,12 @@ #include <stdint.h> #include <deque> +#include <memory> #include <string> #include <vector> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/base/io_buffer.h" #include "net/base/net_export.h" @@ -138,7 +138,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // a network error code otherwise. // // May cause the stream to be closed. - virtual void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) = 0; + virtual void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) = 0; // Called when data is sent. Must not cause the stream to be // closed. @@ -321,7 +321,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // // |length| is the number of bytes received (at most 2^24 - 1) or 0 if // the stream is being closed. - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer); + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer); // Called by the SpdySession when padding is consumed to allow for the stream // receiving window to be updated. @@ -373,7 +373,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // bidirectional streams; for request/response streams, it must be // MORE_DATA_TO_SEND if the request has data to upload, or // NO_MORE_DATA_TO_SEND if not. - int SendRequestHeaders(scoped_ptr<SpdyHeaderBlock> request_headers, + int SendRequestHeaders(std::unique_ptr<SpdyHeaderBlock> request_headers, SpdySendStatus send_status); // Sends a DATA frame. The delegate will be notified via @@ -481,12 +481,12 @@ class NET_EXPORT_PRIVATE SpdyStream { // Produces the SYN_STREAM frame for the stream. The stream must // already be activated. - scoped_ptr<SpdySerializedFrame> ProduceSynStreamFrame(); + std::unique_ptr<SpdySerializedFrame> ProduceSynStreamFrame(); // Produce the initial HEADER frame for the stream with the given // block. The stream must already be activated. - scoped_ptr<SpdySerializedFrame> ProduceHeaderFrame( - scoped_ptr<SpdyHeaderBlock> header_block); + std::unique_ptr<SpdySerializedFrame> ProduceHeaderFrame( + std::unique_ptr<SpdyHeaderBlock> header_block); // Queues the send for next frame of the remaining data in // |pending_send_data_|. Must be called only when @@ -536,7 +536,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // // TODO(akalin): Hang onto this only until we send it. This // necessitates stashing the URL separately. - scoped_ptr<SpdyHeaderBlock> request_headers_; + std::unique_ptr<SpdyHeaderBlock> request_headers_; // Data waiting to be sent, and the close state of the local endpoint // after the data is fully written. @@ -547,7 +547,7 @@ class NET_EXPORT_PRIVATE SpdyStream { // after the data is fully read. Specifically, data received before the // delegate is attached must be buffered and later replayed. A remote FIN // is represented by a final, zero-length buffer. - std::vector<scoped_ptr<SpdyBuffer>> pending_recv_data_; + std::vector<std::unique_ptr<SpdyBuffer>> pending_recv_data_; // The time at which the request was made that resulted in this response. // For cached responses, this time could be "far" in the past. diff --git a/chromium/net/spdy/spdy_stream_test_util.cc b/chromium/net/spdy/spdy_stream_test_util.cc index e0d8e69ada0..e052b881b81 100644 --- a/chromium/net/spdy/spdy_stream_test_util.cc +++ b/chromium/net/spdy/spdy_stream_test_util.cc @@ -30,7 +30,7 @@ SpdyResponseHeadersStatus ClosingDelegate::OnResponseHeadersUpdated( return RESPONSE_HEADERS_ARE_COMPLETE; } -void ClosingDelegate::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) {} +void ClosingDelegate::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) {} void ClosingDelegate::OnDataSent() {} @@ -65,7 +65,7 @@ SpdyResponseHeadersStatus StreamDelegateBase::OnResponseHeadersUpdated( return RESPONSE_HEADERS_ARE_COMPLETE; } -void StreamDelegateBase::OnDataReceived(scoped_ptr<SpdyBuffer> buffer) { +void StreamDelegateBase::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) { if (buffer) received_data_queue_.Enqueue(std::move(buffer)); } diff --git a/chromium/net/spdy/spdy_stream_test_util.h b/chromium/net/spdy/spdy_stream_test_util.h index 9c260ea2e0e..ef3617f6944 100644 --- a/chromium/net/spdy/spdy_stream_test_util.h +++ b/chromium/net/spdy/spdy_stream_test_util.h @@ -5,9 +5,10 @@ #ifndef NET_SPDY_SPDY_STREAM_TEST_UTIL_H_ #define NET_SPDY_SPDY_STREAM_TEST_UTIL_H_ +#include <memory> + #include "base/compiler_specific.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string_piece.h" #include "net/base/io_buffer.h" #include "net/base/test_completion_callback.h" @@ -29,7 +30,7 @@ class ClosingDelegate : public SpdyStream::Delegate { void OnRequestHeadersSent() override; SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) override; - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; void OnDataSent() override; void OnTrailers(const SpdyHeaderBlock& trailers) override; void OnClose(int status) override; @@ -51,7 +52,7 @@ class StreamDelegateBase : public SpdyStream::Delegate { void OnRequestHeadersSent() override; SpdyResponseHeadersStatus OnResponseHeadersUpdated( const SpdyHeaderBlock& response_headers) override; - void OnDataReceived(scoped_ptr<SpdyBuffer> buffer) override; + void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; void OnDataSent() override; void OnTrailers(const SpdyHeaderBlock& trailers) override; void OnClose(int status) override; diff --git a/chromium/net/spdy/spdy_stream_unittest.cc b/chromium/net/spdy/spdy_stream_unittest.cc index e9867dc1ecd..6a56ae35bf6 100644 --- a/chromium/net/spdy/spdy_stream_unittest.cc +++ b/chromium/net/spdy/spdy_stream_unittest.cc @@ -5,14 +5,15 @@ #include "net/spdy/spdy_stream.h" #include <stdint.h> + #include <cstddef> #include <limits> +#include <memory> #include <string> #include <utility> #include <vector> #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/run_loop.h" #include "base/strings/string_piece.h" #include "net/base/completion_callback.h" @@ -134,9 +135,16 @@ class SpdyStreamTest : public ::testing::Test, return writes_.size(); } + void ActivatePushStream(SpdySession* session, SpdyStream* stream) { + std::unique_ptr<SpdyStream> activated = + session->ActivateCreatedStream(stream); + activated->set_stream_id(2); + session->InsertActivatedStream(std::move(activated)); + } + SpdyTestUtil spdy_util_; SpdySessionDependencies session_deps_; - scoped_ptr<HttpNetworkSession> session_; + std::unique_ptr<HttpNetworkSession> session_; private: // Used by Add{Read,Write}() above. @@ -154,19 +162,19 @@ INSTANTIATE_TEST_CASE_P(ProtoPlusDepend, TEST_P(SpdyStreamTest, SendDataAfterOpen) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); AddRead(*resp); - scoped_ptr<SpdySerializedFrame> msg( + std::unique_ptr<SpdySerializedFrame> msg( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddWrite(*msg); - scoped_ptr<SpdySerializedFrame> echo( + std::unique_ptr<SpdySerializedFrame> echo( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddRead(*echo); @@ -191,7 +199,7 @@ TEST_P(SpdyStreamTest, SendDataAfterOpen) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -230,25 +238,25 @@ class StreamDelegateWithTrailers : public test::StreamDelegateWithBody { TEST_P(SpdyStreamTest, Trailers) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); - scoped_ptr<SpdySerializedFrame> msg( + std::unique_ptr<SpdySerializedFrame> msg( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, true)); AddWrite(*msg); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); AddRead(*resp); - scoped_ptr<SpdySerializedFrame> echo( + std::unique_ptr<SpdySerializedFrame> echo( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddRead(*echo); SpdyHeaderBlock late_headers; late_headers["foo"] = "bar"; - scoped_ptr<SpdySerializedFrame> trailers( + std::unique_ptr<SpdySerializedFrame> trailers( spdy_util_.ConstructSpdyResponseHeaders(1, late_headers, false)); AddRead(*trailers); @@ -272,7 +280,7 @@ TEST_P(SpdyStreamTest, Trailers) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -304,36 +312,51 @@ TEST_P(SpdyStreamTest, PushedStream) { base::WeakPtr<SpdySession> spdy_session(CreateDefaultSpdySession()); // Conjure up a stream. - SpdyStream stream(SPDY_PUSH_STREAM, spdy_session, GURL(), DEFAULT_PRIORITY, - SpdySession::GetDefaultInitialWindowSize(kProtoSPDY31), - SpdySession::GetDefaultInitialWindowSize(kProtoSPDY31), - BoundNetLog()); - stream.set_stream_id(2); - EXPECT_FALSE(stream.HasUrlFromHeaders()); + SpdyStreamRequest stream_request; + int result = stream_request.StartRequest(SPDY_PUSH_STREAM, spdy_session, + GURL(), DEFAULT_PRIORITY, + BoundNetLog(), CompletionCallback()); + ASSERT_EQ(OK, result); + base::WeakPtr<SpdyStream> stream = stream_request.ReleaseStream(); + ActivatePushStream(spdy_session.get(), stream.get()); + + EXPECT_FALSE(stream->HasUrlFromHeaders()); // Set required request headers. SpdyHeaderBlock request_headers; spdy_util_.AddUrlToHeaderBlock(kStreamUrl, &request_headers); - stream.OnPushPromiseHeadersReceived(request_headers); + stream->OnPushPromiseHeadersReceived(request_headers); + base::Time response_time = base::Time::Now(); + base::TimeTicks first_byte_time = base::TimeTicks::Now(); // Send some basic response headers. SpdyHeaderBlock response; response[spdy_util_.GetStatusKey()] = "200"; response[spdy_util_.GetVersionKey()] = "OK"; - stream.OnInitialResponseHeadersReceived( - response, base::Time::Now(), base::TimeTicks::Now()); + stream->OnInitialResponseHeadersReceived(response, response_time, + first_byte_time); // And some more headers. // TODO(baranovich): not valid for HTTP 2. SpdyHeaderBlock headers; headers["alpha"] = "beta"; - stream.OnAdditionalResponseHeadersReceived(headers); + stream->OnAdditionalResponseHeadersReceived(headers); + + EXPECT_TRUE(stream->HasUrlFromHeaders()); + EXPECT_EQ(kStreamUrl, stream->GetUrlFromHeaders().spec()); + + StreamDelegateDoNothing delegate(stream->GetWeakPtr()); + stream->SetDelegate(&delegate); - EXPECT_TRUE(stream.HasUrlFromHeaders()); - EXPECT_EQ(kStreamUrl, stream.GetUrlFromHeaders().spec()); + LoadTimingInfo load_timing_info; + EXPECT_TRUE(stream->GetLoadTimingInfo(&load_timing_info)); + EXPECT_EQ(first_byte_time, load_timing_info.push_start); + EXPECT_TRUE(load_timing_info.push_end.is_null()); - StreamDelegateDoNothing delegate(stream.GetWeakPtr()); - stream.SetDelegate(&delegate); + stream->OnDataReceived(nullptr); + LoadTimingInfo load_timing_info2; + EXPECT_TRUE(stream->GetLoadTimingInfo(&load_timing_info2)); + EXPECT_FALSE(load_timing_info2.push_end.is_null()); base::RunLoop().RunUntilIdle(); @@ -346,19 +369,19 @@ TEST_P(SpdyStreamTest, PushedStream) { TEST_P(SpdyStreamTest, StreamError) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*resp); - scoped_ptr<SpdySerializedFrame> msg( + std::unique_ptr<SpdySerializedFrame> msg( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddWrite(*msg); - scoped_ptr<SpdySerializedFrame> echo( + std::unique_ptr<SpdySerializedFrame> echo( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddRead(*echo); @@ -385,7 +408,7 @@ TEST_P(SpdyStreamTest, StreamError) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -422,21 +445,22 @@ TEST_P(SpdyStreamTest, StreamError) { TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); std::string chunk_data(kMaxSpdyFrameChunkSize, 'x'); - scoped_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame( 1, chunk_data.data(), chunk_data.length(), false)); AddWrite(*chunk); AddWrite(*chunk); - scoped_ptr<SpdySerializedFrame> last_chunk(spdy_util_.ConstructSpdyBodyFrame( - 1, chunk_data.data(), chunk_data.length(), true)); + std::unique_ptr<SpdySerializedFrame> last_chunk( + spdy_util_.ConstructSpdyBodyFrame(1, chunk_data.data(), + chunk_data.length(), true)); AddWrite(*last_chunk); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); AddRead(*resp); @@ -462,7 +486,7 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -483,16 +507,16 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenRequestResponse) { TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyPostSynReply(NULL, 0)); AddRead(*resp); std::string chunk_data(kMaxSpdyFrameChunkSize, 'x'); - scoped_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame( + std::unique_ptr<SpdySerializedFrame> chunk(spdy_util_.ConstructSpdyBodyFrame( 1, chunk_data.data(), chunk_data.length(), false)); AddWrite(*chunk); AddWrite(*chunk); @@ -520,7 +544,7 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -540,16 +564,16 @@ TEST_P(SpdyStreamTest, SendLargeDataAfterOpenBidirectional) { TEST_P(SpdyStreamTest, UpperCaseHeaders) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> syn( + std::unique_ptr<SpdySerializedFrame> syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); AddWrite(*syn); const char* const kExtraHeaders[] = {"X-UpperCase", "yes"}; - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(kExtraHeaders, 1, 1)); AddRead(*reply); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_PROTOCOL_ERROR)); AddWrite(*rst); @@ -574,7 +598,7 @@ TEST_P(SpdyStreamTest, UpperCaseHeaders) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -589,20 +613,20 @@ TEST_P(SpdyStreamTest, UpperCaseHeaders) { TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> syn( + std::unique_ptr<SpdySerializedFrame> syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); AddWrite(*syn); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*reply); const char* const extra_headers[] = {"X-UpperCase", "yes"}; - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(extra_headers, 1, 2, 1, kStreamUrl)); AddRead(*push); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); AddWrite(*rst); @@ -629,7 +653,7 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -652,15 +676,15 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersOnPush) { TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> syn( + std::unique_ptr<SpdySerializedFrame> syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); AddWrite(*syn); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*reply); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl)); AddRead(*push); @@ -668,13 +692,13 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) { SpdyHeaderBlock late_headers; late_headers["X-UpperCase"] = "yes"; - scoped_ptr<SpdySerializedFrame> headers_frame( + std::unique_ptr<SpdySerializedFrame> headers_frame( spdy_util_.ConstructSpdyReply(2, late_headers)); AddRead(*headers_frame); AddWritePause(); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); AddWrite(*rst); @@ -699,7 +723,7 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -728,15 +752,15 @@ TEST_P(SpdyStreamTest, UpperCaseHeadersInHeadersFrame) { TEST_P(SpdyStreamTest, DuplicateHeaders) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> syn( + std::unique_ptr<SpdySerializedFrame> syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); AddWrite(*syn); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*reply); - scoped_ptr<SpdySerializedFrame> push( + std::unique_ptr<SpdySerializedFrame> push( spdy_util_.ConstructSpdyPush(NULL, 0, 2, 1, kStreamUrl)); AddRead(*push); @@ -744,13 +768,13 @@ TEST_P(SpdyStreamTest, DuplicateHeaders) { SpdyHeaderBlock late_headers; late_headers[spdy_util_.GetStatusKey()] = "500 Server Error"; - scoped_ptr<SpdySerializedFrame> headers_frame( + std::unique_ptr<SpdySerializedFrame> headers_frame( spdy_util_.ConstructSpdyReply(2, late_headers)); AddRead(*headers_frame); AddReadPause(); - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(2, RST_STREAM_PROTOCOL_ERROR)); AddWrite(*rst); @@ -775,7 +799,7 @@ TEST_P(SpdyStreamTest, DuplicateHeaders) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND)); @@ -803,7 +827,7 @@ TEST_P(SpdyStreamTest, DuplicateHeaders) { // to overflow an int32_t. The SpdyStream should handle that case // gracefully. TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) { - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); @@ -811,7 +835,7 @@ TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) { // Triggered by the overflowing call to IncreaseSendWindowSize // below. - scoped_ptr<SpdySerializedFrame> rst( + std::unique_ptr<SpdySerializedFrame> rst( spdy_util_.ConstructSpdyRstStream(1, RST_STREAM_FLOW_CONTROL_ERROR)); AddWrite(*rst); @@ -836,7 +860,7 @@ TEST_P(SpdyStreamTest, IncreaseSendWindowSizeOverflow) { StreamDelegateSendImmediate delegate(stream, kPostBodyStringPiece); stream->SetDelegate(&delegate); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -895,15 +919,15 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest( const UnstallFunction& unstall_function) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); - scoped_ptr<SpdySerializedFrame> body( + std::unique_ptr<SpdySerializedFrame> body( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, true)); AddWrite(*body); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*resp); @@ -929,7 +953,7 @@ void SpdyStreamTest::RunResumeAfterUnstallRequestResponseTest( EXPECT_FALSE(stream->HasUrlFromHeaders()); EXPECT_FALSE(stream->send_stalled_by_flow_control()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -971,21 +995,21 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest( const UnstallFunction& unstall_function) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( + std::unique_ptr<SpdySerializedFrame> req(spdy_util_.ConstructSpdyPost( kStreamUrl, 1, kPostBodyLength, LOWEST, NULL, 0)); AddWrite(*req); AddReadPause(); - scoped_ptr<SpdySerializedFrame> resp( + std::unique_ptr<SpdySerializedFrame> resp( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*resp); - scoped_ptr<SpdySerializedFrame> msg( + std::unique_ptr<SpdySerializedFrame> msg( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddWrite(*msg); - scoped_ptr<SpdySerializedFrame> echo( + std::unique_ptr<SpdySerializedFrame> echo( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddRead(*echo); @@ -1010,7 +1034,7 @@ void SpdyStreamTest::RunResumeAfterUnstallBidirectionalTest( EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructPostHeaderBlock(kStreamUrl, kPostBodyLength)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), MORE_DATA_TO_SEND)); @@ -1055,19 +1079,19 @@ TEST_P(SpdyStreamTest, ResumeAfterSendWindowSizeAdjustBidirectional) { TEST_P(SpdyStreamTest, ReceivedBytes) { GURL url(kStreamUrl); - scoped_ptr<SpdySerializedFrame> syn( + std::unique_ptr<SpdySerializedFrame> syn( spdy_util_.ConstructSpdyGet(nullptr, 0, 1, LOWEST, true)); AddWrite(*syn); AddReadPause(); - scoped_ptr<SpdySerializedFrame> reply( + std::unique_ptr<SpdySerializedFrame> reply( spdy_util_.ConstructSpdyGetSynReply(NULL, 0, 1)); AddRead(*reply); AddReadPause(); - scoped_ptr<SpdySerializedFrame> msg( + std::unique_ptr<SpdySerializedFrame> msg( spdy_util_.ConstructSpdyBodyFrame(1, kPostBody, kPostBodyLength, false)); AddRead(*msg); @@ -1094,7 +1118,7 @@ TEST_P(SpdyStreamTest, ReceivedBytes) { EXPECT_FALSE(stream->HasUrlFromHeaders()); - scoped_ptr<SpdyHeaderBlock> headers( + std::unique_ptr<SpdyHeaderBlock> headers( spdy_util_.ConstructGetHeaderBlock(kStreamUrl)); EXPECT_EQ(ERR_IO_PENDING, stream->SendRequestHeaders(std::move(headers), NO_MORE_DATA_TO_SEND)); diff --git a/chromium/net/spdy/spdy_test_util_common.cc b/chromium/net/spdy/spdy_test_util_common.cc index 53e73345364..048bf721767 100644 --- a/chromium/net/spdy/spdy_test_util_common.cc +++ b/chromium/net/spdy/spdy_test_util_common.cc @@ -5,12 +5,14 @@ #include "net/spdy/spdy_test_util_common.h" #include <stdint.h> + #include <cstddef> +#include <memory> #include <utility> #include "base/compiler_specific.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" +#include "base/memory/ptr_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" #include "net/base/host_port_pair.h" @@ -211,8 +213,8 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface { bool fin) override {} void OnStreamFrameData(SpdyStreamId stream_id, const char* data, - size_t len, - bool fin) override {} + size_t len) override {} + void OnStreamEnd(SpdyStreamId stream_id) override {} void OnStreamPadding(SpdyStreamId stream_id, size_t len) override {} SpdyHeadersHandlerInterface* OnHeaderFrameStart( SpdyStreamId stream_id) override { @@ -226,7 +228,7 @@ class PriorityGetter : public BufferedSpdyFramerVisitorInterface { SpdyRstStreamStatus status) override {} void OnGoAway(SpdyStreamId last_accepted_stream_id, SpdyGoAwayStatus status, - StringPiece debug_data) override {} + base::StringPiece debug_data) override {} void OnWindowUpdate(SpdyStreamId stream_id, int delta_window_size) override {} void OnPushPromise(SpdyStreamId stream_id, SpdyStreamId promised_stream_id, @@ -346,14 +348,15 @@ SpdySessionDependencies::SpdySessionDependencies(NextProto protocol) enable_priority_dependencies(true), enable_spdy31(true), enable_quic(false), + enable_alternative_service_for_insecure_origins(true), protocol(protocol), session_max_recv_window_size( SpdySession::GetDefaultInitialWindowSize(protocol)), stream_max_recv_window_size( SpdySession::GetDefaultInitialWindowSize(protocol)), time_func(&base::TimeTicks::Now), - parse_alternative_services(false), - enable_alternative_service_with_different_host(false), + parse_alternative_services(true), + enable_alternative_service_with_different_host(true), net_log(NULL) { DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol; @@ -368,7 +371,7 @@ SpdySessionDependencies::SpdySessionDependencies(NextProto protocol) SpdySessionDependencies::SpdySessionDependencies( NextProto protocol, - scoped_ptr<ProxyService> proxy_service) + std::unique_ptr<ProxyService> proxy_service) : host_resolver(new MockHostResolver), cert_verifier(new MockCertVerifier), channel_id_service(nullptr), @@ -385,14 +388,15 @@ SpdySessionDependencies::SpdySessionDependencies( enable_priority_dependencies(true), enable_spdy31(true), enable_quic(false), + enable_alternative_service_for_insecure_origins(true), protocol(protocol), session_max_recv_window_size( SpdySession::GetDefaultInitialWindowSize(protocol)), stream_max_recv_window_size( SpdySession::GetDefaultInitialWindowSize(protocol)), time_func(&base::TimeTicks::Now), - parse_alternative_services(false), - enable_alternative_service_with_different_host(false), + parse_alternative_services(true), + enable_alternative_service_with_different_host(true), net_log(NULL) { DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol; } @@ -400,11 +404,12 @@ SpdySessionDependencies::SpdySessionDependencies( SpdySessionDependencies::~SpdySessionDependencies() {} // static -scoped_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession( +std::unique_ptr<HttpNetworkSession> SpdySessionDependencies::SpdyCreateSession( SpdySessionDependencies* session_deps) { HttpNetworkSession::Params params = CreateSessionParams(session_deps); params.client_socket_factory = session_deps->socket_factory.get(); - scoped_ptr<HttpNetworkSession> http_session(new HttpNetworkSession(params)); + std::unique_ptr<HttpNetworkSession> http_session( + new HttpNetworkSession(params)); SpdySessionPoolPeer pool_peer(http_session->spdy_session_pool()); pool_peer.SetEnableSendingInitialData(false); return http_session; @@ -436,6 +441,8 @@ HttpNetworkSession::Params SpdySessionDependencies::CreateSessionParams( session_deps->enable_priority_dependencies; params.enable_spdy31 = session_deps->enable_spdy31; params.enable_quic = session_deps->enable_quic; + params.enable_alternative_service_for_insecure_origins = + session_deps->enable_alternative_service_for_insecure_origins; params.spdy_default_protocol = session_deps->protocol; params.spdy_session_max_recv_window_size = session_deps->session_max_recv_window_size; @@ -454,17 +461,18 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol) : storage_(this) { DCHECK(next_proto_is_spdy(protocol)) << "Invalid protocol: " << protocol; - storage_.set_host_resolver(scoped_ptr<HostResolver>(new MockHostResolver)); - storage_.set_cert_verifier(make_scoped_ptr(new MockCertVerifier)); + storage_.set_host_resolver( + std::unique_ptr<HostResolver>(new MockHostResolver)); + storage_.set_cert_verifier(base::WrapUnique(new MockCertVerifier)); storage_.set_transport_security_state( - make_scoped_ptr(new TransportSecurityState)); + base::WrapUnique(new TransportSecurityState)); storage_.set_proxy_service(ProxyService::CreateDirect()); storage_.set_ssl_config_service(new SSLConfigServiceDefaults); storage_.set_http_auth_handler_factory( HttpAuthHandlerFactory::CreateDefault(host_resolver())); storage_.set_http_server_properties( - scoped_ptr<HttpServerProperties>(new HttpServerPropertiesImpl())); - storage_.set_job_factory(make_scoped_ptr(new URLRequestJobFactoryImpl())); + std::unique_ptr<HttpServerProperties>(new HttpServerPropertiesImpl())); + storage_.set_job_factory(base::WrapUnique(new URLRequestJobFactoryImpl())); HttpNetworkSession::Params params; params.client_socket_factory = &socket_factory_; params.host_resolver = host_resolver(); @@ -477,11 +485,11 @@ SpdyURLRequestContext::SpdyURLRequestContext(NextProto protocol) params.spdy_default_protocol = protocol; params.http_server_properties = http_server_properties(); storage_.set_http_network_session( - make_scoped_ptr(new HttpNetworkSession(params))); + base::WrapUnique(new HttpNetworkSession(params))); SpdySessionPoolPeer pool_peer( storage_.http_network_session()->spdy_session_pool()); pool_peer.SetEnableSendingInitialData(false); - storage_.set_http_transaction_factory(make_scoped_ptr( + storage_.set_http_transaction_factory(base::WrapUnique( new HttpCache(storage_.http_network_session(), HttpCache::DefaultBackend::InMemory(0), false))); } @@ -509,7 +517,7 @@ base::WeakPtr<SpdySession> CreateSpdySessionHelper( key.host_port_pair(), false, OnHostResolutionCallback(), TransportSocketParams::COMBINE_CONNECT_AND_WRITE_DEFAULT)); - scoped_ptr<ClientSocketHandle> connection(new ClientSocketHandle); + std::unique_ptr<ClientSocketHandle> connection(new ClientSocketHandle); TestCompletionCallback callback; int rv = ERR_UNEXPECTED; @@ -642,9 +650,10 @@ base::WeakPtr<SpdySession> CreateFakeSpdySessionHelper( Error expected_status) { EXPECT_NE(expected_status, ERR_IO_PENDING); EXPECT_FALSE(HasSpdySession(pool, key)); - scoped_ptr<ClientSocketHandle> handle(new ClientSocketHandle()); - handle->SetSocket(scoped_ptr<StreamSocket>(new FakeSpdySessionClientSocket( - expected_status == OK ? ERR_IO_PENDING : expected_status))); + std::unique_ptr<ClientSocketHandle> handle(new ClientSocketHandle()); + handle->SetSocket( + std::unique_ptr<StreamSocket>(new FakeSpdySessionClientSocket( + expected_status == OK ? ERR_IO_PENDING : expected_status))); base::WeakPtr<SpdySession> spdy_session = pool->CreateAvailableSessionFromSocket( key, std::move(handle), BoundNetLog(), OK, true /* is_secure */); @@ -714,30 +723,30 @@ void SpdyTestUtil::AddUrlToHeaderBlock(base::StringPiece url, (*headers)[GetPathKey()] = path; } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlock( base::StringPiece url) const { return ConstructHeaderBlock("GET", url, NULL); } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlockForProxy( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructGetHeaderBlockForProxy( base::StringPiece url) const { - scoped_ptr<SpdyHeaderBlock> headers(ConstructGetHeaderBlock(url)); + std::unique_ptr<SpdyHeaderBlock> headers(ConstructGetHeaderBlock(url)); return headers; } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeadHeaderBlock( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeadHeaderBlock( base::StringPiece url, int64_t content_length) const { return ConstructHeaderBlock("HEAD", url, nullptr); } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPostHeaderBlock( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPostHeaderBlock( base::StringPiece url, int64_t content_length) const { return ConstructHeaderBlock("POST", url, &content_length); } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPutHeaderBlock( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPutHeaderBlock( base::StringPiece url, int64_t content_length) const { return ConstructHeaderBlock("PUT", url, &content_length); @@ -745,7 +754,7 @@ scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructPutHeaderBlock( SpdySerializedFrame* SpdyTestUtil::ConstructSpdyFrame( const SpdyHeaderInfo& header_info, - scoped_ptr<SpdyHeaderBlock> headers) const { + std::unique_ptr<SpdyHeaderBlock> headers) const { BufferedSpdyFramer framer(spdy_version_); SpdySerializedFrame* frame = NULL; switch (header_info.kind) { @@ -787,7 +796,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyFrame( int extra_header_count, const char* const tail_headers[], int tail_header_count) const { - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); AppendToHeaderBlock(extra_headers, extra_header_count, headers.get()); if (tail_headers && tail_header_count) AppendToHeaderBlock(tail_headers, tail_header_count, headers.get()); @@ -892,7 +901,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyGet( const char* const url, SpdyStreamId stream_id, RequestPriority request_priority) { - scoped_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url)); + std::unique_ptr<SpdyHeaderBlock> block(ConstructGetHeaderBlock(url)); return ConstructSpdySyn(stream_id, *block, request_priority, true); } @@ -963,7 +972,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPush( response_spdy_framer_.SerializeFrame(headers)); int joint_data_size = push_promise_frame.size() + headers_frame.size(); - scoped_ptr<char[]> data(new char[joint_data_size]); + std::unique_ptr<char[]> data(new char[joint_data_size]); const SpdySerializedFrame* frames[2] = { &push_promise_frame, &headers_frame, }; @@ -1010,7 +1019,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPush( response_spdy_framer_.SerializeFrame(headers)); int joint_data_size = push_promise_frame.size() + headers_frame.size(); - scoped_ptr<char[]> data(new char[joint_data_size]); + std::unique_ptr<char[]> data(new char[joint_data_size]); const SpdySerializedFrame* frames[2] = { &push_promise_frame, &headers_frame, }; @@ -1022,7 +1031,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPush( } SpdySerializedFrame* SpdyTestUtil::ConstructInitialSpdyPushFrame( - scoped_ptr<SpdyHeaderBlock> headers, + std::unique_ptr<SpdyHeaderBlock> headers, int stream_id, int associated_stream_id) { if (spdy_version() < HTTP2) { @@ -1172,7 +1181,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyPost( RequestPriority priority, const char* const extra_headers[], int extra_header_count) { - scoped_ptr<SpdyHeaderBlock> block( + std::unique_ptr<SpdyHeaderBlock> block( ConstructPostHeaderBlock(url, content_length)); AppendToHeaderBlock(extra_headers, extra_header_count, block.get()); return ConstructSpdySyn(stream_id, *block, priority, false); @@ -1228,7 +1237,7 @@ SpdySerializedFrame* SpdyTestUtil::ConstructSpdyBodyFrame(int stream_id, } SpdySerializedFrame* SpdyTestUtil::ConstructWrappedSpdyFrame( - const scoped_ptr<SpdySerializedFrame>& frame, + const std::unique_ptr<SpdySerializedFrame>& frame, int stream_id) { return ConstructSpdyBodyFrame(stream_id, frame->data(), frame->size(), false); @@ -1275,13 +1284,13 @@ const char* SpdyTestUtil::GetPathKey() const { return ":path"; } -scoped_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock( +std::unique_ptr<SpdyHeaderBlock> SpdyTestUtil::ConstructHeaderBlock( base::StringPiece method, base::StringPiece url, int64_t* content_length) const { std::string scheme, host, path; ParseUrl(url.data(), &scheme, &host, &path); - scoped_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); + std::unique_ptr<SpdyHeaderBlock> headers(new SpdyHeaderBlock()); if (include_version_header()) { (*headers)[GetVersionKey()] = "HTTP/1.1"; } diff --git a/chromium/net/spdy/spdy_test_util_common.h b/chromium/net/spdy/spdy_test_util_common.h index c25fa968878..43bf93e61ca 100644 --- a/chromium/net/spdy/spdy_test_util_common.h +++ b/chromium/net/spdy/spdy_test_util_common.h @@ -8,12 +8,12 @@ #include <stddef.h> #include <stdint.h> +#include <memory> #include <string> #include <vector> #include "base/macros.h" #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "crypto/ec_private_key.h" #include "crypto/ec_signature_creator.h" #include "net/base/completion_callback.h" @@ -175,24 +175,24 @@ struct SpdySessionDependencies { // Custom proxy service dependency. SpdySessionDependencies(NextProto protocol, - scoped_ptr<ProxyService> proxy_service); + std::unique_ptr<ProxyService> proxy_service); ~SpdySessionDependencies(); - static scoped_ptr<HttpNetworkSession> SpdyCreateSession( + static std::unique_ptr<HttpNetworkSession> SpdyCreateSession( SpdySessionDependencies* session_deps); static HttpNetworkSession::Params CreateSessionParams( SpdySessionDependencies* session_deps); // NOTE: host_resolver must be ordered before http_auth_handler_factory. - scoped_ptr<MockHostResolverBase> host_resolver; - scoped_ptr<CertVerifier> cert_verifier; - scoped_ptr<ChannelIDService> channel_id_service; - scoped_ptr<TransportSecurityState> transport_security_state; - scoped_ptr<ProxyService> proxy_service; + std::unique_ptr<MockHostResolverBase> host_resolver; + std::unique_ptr<CertVerifier> cert_verifier; + std::unique_ptr<ChannelIDService> channel_id_service; + std::unique_ptr<TransportSecurityState> transport_security_state; + std::unique_ptr<ProxyService> proxy_service; scoped_refptr<SSLConfigService> ssl_config_service; - scoped_ptr<MockClientSocketFactory> socket_factory; - scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; + std::unique_ptr<MockClientSocketFactory> socket_factory; + std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory; HttpServerPropertiesImpl http_server_properties; bool enable_ip_pooling; bool enable_ping; @@ -201,11 +201,12 @@ struct SpdySessionDependencies { bool enable_priority_dependencies; bool enable_spdy31; bool enable_quic; + bool enable_alternative_service_for_insecure_origins; NextProto protocol; size_t session_max_recv_window_size; size_t stream_max_recv_window_size; SpdySession::TimeFunc time_func; - scoped_ptr<ProxyDelegate> proxy_delegate; + std::unique_ptr<ProxyDelegate> proxy_delegate; bool parse_alternative_services; bool enable_alternative_service_with_different_host; NetLog* net_log; @@ -291,17 +292,17 @@ class SpdyTestUtil { void AddUrlToHeaderBlock(base::StringPiece url, SpdyHeaderBlock* headers) const; - scoped_ptr<SpdyHeaderBlock> ConstructGetHeaderBlock( + std::unique_ptr<SpdyHeaderBlock> ConstructGetHeaderBlock( base::StringPiece url) const; - scoped_ptr<SpdyHeaderBlock> ConstructGetHeaderBlockForProxy( + std::unique_ptr<SpdyHeaderBlock> ConstructGetHeaderBlockForProxy( base::StringPiece url) const; - scoped_ptr<SpdyHeaderBlock> ConstructHeadHeaderBlock( + std::unique_ptr<SpdyHeaderBlock> ConstructHeadHeaderBlock( base::StringPiece url, int64_t content_length) const; - scoped_ptr<SpdyHeaderBlock> ConstructPostHeaderBlock( + std::unique_ptr<SpdyHeaderBlock> ConstructPostHeaderBlock( base::StringPiece url, int64_t content_length) const; - scoped_ptr<SpdyHeaderBlock> ConstructPutHeaderBlock( + std::unique_ptr<SpdyHeaderBlock> ConstructPutHeaderBlock( base::StringPiece url, int64_t content_length) const; @@ -310,7 +311,7 @@ class SpdyTestUtil { // frame. SpdySerializedFrame* ConstructSpdyFrame( const SpdyHeaderInfo& header_info, - scoped_ptr<SpdyHeaderBlock> headers) const; + std::unique_ptr<SpdyHeaderBlock> headers) const; // Construct a SPDY frame. If it is a SYN_STREAM or SYN_REPLY frame (as // specified in header_info.kind), the headers provided in extra_headers and @@ -407,7 +408,7 @@ class SpdyTestUtil { const char* location); SpdySerializedFrame* ConstructInitialSpdyPushFrame( - scoped_ptr<SpdyHeaderBlock> headers, + std::unique_ptr<SpdyHeaderBlock> headers, int stream_id, int associated_stream_id); @@ -509,7 +510,7 @@ class SpdyTestUtil { // Wraps |frame| in the payload of a data frame in stream |stream_id|. SpdySerializedFrame* ConstructWrappedSpdyFrame( - const scoped_ptr<SpdySerializedFrame>& frame, + const std::unique_ptr<SpdySerializedFrame>& frame, int stream_id); // Called when necessary (when it will affect stream dependency specification @@ -541,7 +542,7 @@ class SpdyTestUtil { private: // |content_length| may be NULL, in which case the content-length // header will be omitted. - scoped_ptr<SpdyHeaderBlock> ConstructHeaderBlock( + std::unique_ptr<SpdyHeaderBlock> ConstructHeaderBlock( base::StringPiece method, base::StringPiece url, int64_t* content_length) const; diff --git a/chromium/net/spdy/spdy_test_utils.cc b/chromium/net/spdy/spdy_test_utils.cc index acc61c17914..76ad5de4d54 100644 --- a/chromium/net/spdy/spdy_test_utils.cc +++ b/chromium/net/spdy/spdy_test_utils.cc @@ -5,11 +5,11 @@ #include "net/spdy/spdy_test_utils.h" #include <cstring> +#include <memory> #include <vector> #include "base/base64.h" #include "base/logging.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "base/sys_byteorder.h" #include "net/http/transport_security_state.h" @@ -68,7 +68,7 @@ void CompareCharArraysWithHexError(const string& description, const int expected_len) { const int min_len = std::min(actual_len, expected_len); const int max_len = std::max(actual_len, expected_len); - scoped_ptr<bool[]> marks(new bool[max_len]); + std::unique_ptr<bool[]> marks(new bool[max_len]); bool identical = (actual_len == expected_len); for (int i = 0; i < min_len; ++i) { if (actual[i] != expected[i]) { diff --git a/chromium/net/spdy/spdy_test_utils.h b/chromium/net/spdy/spdy_test_utils.h index 388cb2baee4..297fcd19e76 100644 --- a/chromium/net/spdy/spdy_test_utils.h +++ b/chromium/net/spdy/spdy_test_utils.h @@ -11,9 +11,13 @@ #include <string> #include "base/strings/string_piece.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_header_block.h" #include "net/spdy/spdy_headers_handler_interface.h" #include "net/spdy/spdy_protocol.h" +#include "net/test/gtest_util.h" + +#define EXPECT_SPDY_BUG EXPECT_DFATAL namespace net { diff --git a/chromium/net/spdy/spdy_write_queue.cc b/chromium/net/spdy/spdy_write_queue.cc index a8e6553283a..b49573cdd6a 100644 --- a/chromium/net/spdy/spdy_write_queue.cc +++ b/chromium/net/spdy/spdy_write_queue.cc @@ -46,7 +46,7 @@ bool SpdyWriteQueue::IsEmpty() const { void SpdyWriteQueue::Enqueue(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> frame_producer, + std::unique_ptr<SpdyBufferProducer> frame_producer, const base::WeakPtr<SpdyStream>& stream) { CHECK(!removing_writes_); CHECK_GE(priority, MINIMUM_PRIORITY); @@ -57,9 +57,10 @@ void SpdyWriteQueue::Enqueue(RequestPriority priority, PendingWrite(frame_type, frame_producer.release(), stream)); } -bool SpdyWriteQueue::Dequeue(SpdyFrameType* frame_type, - scoped_ptr<SpdyBufferProducer>* frame_producer, - base::WeakPtr<SpdyStream>* stream) { +bool SpdyWriteQueue::Dequeue( + SpdyFrameType* frame_type, + std::unique_ptr<SpdyBufferProducer>* frame_producer, + base::WeakPtr<SpdyStream>* stream) { CHECK(!removing_writes_); for (int i = MAXIMUM_PRIORITY; i >= MINIMUM_PRIORITY; --i) { if (!queue_[i].empty()) { diff --git a/chromium/net/spdy/spdy_write_queue.h b/chromium/net/spdy/spdy_write_queue.h index 8383e7a3cea..ebc81579751 100644 --- a/chromium/net/spdy/spdy_write_queue.h +++ b/chromium/net/spdy/spdy_write_queue.h @@ -6,9 +6,9 @@ #define NET_SPDY_SPDY_WRITE_QUEUE_H_ #include <deque> +#include <memory> #include "base/macros.h" -#include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "net/base/net_export.h" #include "net/base/request_priority.h" @@ -38,7 +38,7 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { // must remain non-NULL until the write is dequeued or removed. void Enqueue(RequestPriority priority, SpdyFrameType frame_type, - scoped_ptr<SpdyBufferProducer> frame_producer, + std::unique_ptr<SpdyBufferProducer> frame_producer, const base::WeakPtr<SpdyStream>& stream); // Dequeues the frame producer with the highest priority that was @@ -46,7 +46,7 @@ class NET_EXPORT_PRIVATE SpdyWriteQueue { // fills in |frame_type|, |frame_producer|, and |stream| if // successful -- otherwise, just returns false. bool Dequeue(SpdyFrameType* frame_type, - scoped_ptr<SpdyBufferProducer>* frame_producer, + std::unique_ptr<SpdyBufferProducer>* frame_producer, base::WeakPtr<SpdyStream>* stream); // Removes all pending writes for the given stream, which must be diff --git a/chromium/net/spdy/spdy_write_queue_unittest.cc b/chromium/net/spdy/spdy_write_queue_unittest.cc index da9d98778f7..9ffacc840a9 100644 --- a/chromium/net/spdy/spdy_write_queue_unittest.cc +++ b/chromium/net/spdy/spdy_write_queue_unittest.cc @@ -6,11 +6,11 @@ #include <cstddef> #include <cstring> +#include <memory> #include <string> #include <utility> #include "base/memory/ref_counted.h" -#include "base/memory/scoped_ptr.h" #include "base/strings/string_number_conversions.h" #include "net/base/request_priority.h" #include "net/log/net_log.h" @@ -32,17 +32,18 @@ class SpdyWriteQueueTest : public ::testing::Test {}; // Makes a SpdyFrameProducer producing a frame with the data in the // given string. -scoped_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) { - scoped_ptr<char[]> data(new char[s.size()]); +std::unique_ptr<SpdyBufferProducer> StringToProducer(const std::string& s) { + std::unique_ptr<char[]> data(new char[s.size()]); std::memcpy(data.get(), s.data(), s.size()); - return scoped_ptr<SpdyBufferProducer>(new SimpleBufferProducer( - scoped_ptr<SpdyBuffer>(new SpdyBuffer(scoped_ptr<SpdySerializedFrame>( - new SpdySerializedFrame(data.release(), s.size(), true)))))); + return std::unique_ptr<SpdyBufferProducer>( + new SimpleBufferProducer(std::unique_ptr<SpdyBuffer>( + new SpdyBuffer(std::unique_ptr<SpdySerializedFrame>( + new SpdySerializedFrame(data.release(), s.size(), true)))))); } // Makes a SpdyBufferProducer producing a frame with the data in the // given int (converted to a string). -scoped_ptr<SpdyBufferProducer> IntToProducer(int i) { +std::unique_ptr<SpdyBufferProducer> IntToProducer(int i) { return StringToProducer(base::IntToString(i)); } @@ -56,13 +57,15 @@ class RequeingBufferProducer : public SpdyBufferProducer { base::Bind(RequeingBufferProducer::ConsumeCallback, queue)); } - scoped_ptr<SpdyBuffer> ProduceBuffer() override { return std::move(buffer_); } + std::unique_ptr<SpdyBuffer> ProduceBuffer() override { + return std::move(buffer_); + } static void ConsumeCallback(SpdyWriteQueue* queue, size_t size, SpdyBuffer::ConsumeSource source) { - scoped_ptr<SpdyBufferProducer> producer( - new SimpleBufferProducer(scoped_ptr<SpdyBuffer>( + std::unique_ptr<SpdyBufferProducer> producer( + new SimpleBufferProducer(std::unique_ptr<SpdyBuffer>( new SpdyBuffer(kRequeued, arraysize(kRequeued))))); queue->Enqueue(MEDIUM, RST_STREAM, std::move(producer), @@ -70,19 +73,19 @@ class RequeingBufferProducer : public SpdyBufferProducer { } private: - scoped_ptr<SpdyBuffer> buffer_; + std::unique_ptr<SpdyBuffer> buffer_; }; // Produces a frame with the given producer and returns a copy of its // data as a string. -std::string ProducerToString(scoped_ptr<SpdyBufferProducer> producer) { - scoped_ptr<SpdyBuffer> buffer = producer->ProduceBuffer(); +std::string ProducerToString(std::unique_ptr<SpdyBufferProducer> producer) { + std::unique_ptr<SpdyBuffer> buffer = producer->ProduceBuffer(); return std::string(buffer->GetRemainingData(), buffer->GetRemainingSize()); } // Produces a frame with the given producer and returns a copy of its // data as an int (converted from a string). -int ProducerToInt(scoped_ptr<SpdyBufferProducer> producer) { +int ProducerToInt(std::unique_ptr<SpdyBufferProducer> producer) { int i = 0; EXPECT_TRUE(base::StringToInt(ProducerToString(std::move(producer)), &i)); return i; @@ -102,12 +105,14 @@ SpdyStream* MakeTestStream(RequestPriority priority) { TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyBufferProducer> producer_low = StringToProducer("LOW"); - scoped_ptr<SpdyBufferProducer> producer_medium = StringToProducer("MEDIUM"); - scoped_ptr<SpdyBufferProducer> producer_highest = StringToProducer("HIGHEST"); + std::unique_ptr<SpdyBufferProducer> producer_low = StringToProducer("LOW"); + std::unique_ptr<SpdyBufferProducer> producer_medium = + StringToProducer("MEDIUM"); + std::unique_ptr<SpdyBufferProducer> producer_highest = + StringToProducer("HIGHEST"); - scoped_ptr<SpdyStream> stream_medium(MakeTestStream(MEDIUM)); - scoped_ptr<SpdyStream> stream_highest(MakeTestStream(HIGHEST)); + std::unique_ptr<SpdyStream> stream_medium(MakeTestStream(MEDIUM)); + std::unique_ptr<SpdyStream> stream_highest(MakeTestStream(HIGHEST)); // A NULL stream should still work. write_queue.Enqueue(LOW, SYN_STREAM, std::move(producer_low), @@ -118,7 +123,7 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { stream_highest->GetWeakPtr()); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(RST_STREAM, frame_type); @@ -143,13 +148,13 @@ TEST_F(SpdyWriteQueueTest, DequeuesByPriority) { TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyBufferProducer> producer1 = IntToProducer(1); - scoped_ptr<SpdyBufferProducer> producer2 = IntToProducer(2); - scoped_ptr<SpdyBufferProducer> producer3 = IntToProducer(3); + std::unique_ptr<SpdyBufferProducer> producer1 = IntToProducer(1); + std::unique_ptr<SpdyBufferProducer> producer2 = IntToProducer(2); + std::unique_ptr<SpdyBufferProducer> producer3 = IntToProducer(3); - scoped_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); - scoped_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); - scoped_ptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY)); write_queue.Enqueue(DEFAULT_PRIORITY, SYN_STREAM, std::move(producer1), stream1->GetWeakPtr()); @@ -159,7 +164,7 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { stream3->GetWeakPtr()); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(SYN_STREAM, frame_type); @@ -185,8 +190,8 @@ TEST_F(SpdyWriteQueueTest, DequeuesFIFO) { TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); - scoped_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); for (int i = 0; i < 100; ++i) { base::WeakPtr<SpdyStream> stream = @@ -198,7 +203,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { for (int i = 0; i < 100; i += 3) { SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); EXPECT_EQ(SYN_STREAM, frame_type); @@ -207,7 +212,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { } SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); } @@ -219,14 +224,14 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStream) { TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) { SpdyWriteQueue write_queue; - scoped_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream1(MakeTestStream(DEFAULT_PRIORITY)); stream1->set_stream_id(1); - scoped_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream2(MakeTestStream(DEFAULT_PRIORITY)); stream2->set_stream_id(3); - scoped_ptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream3(MakeTestStream(DEFAULT_PRIORITY)); stream3->set_stream_id(5); // No stream id assigned. - scoped_ptr<SpdyStream> stream4(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream4(MakeTestStream(DEFAULT_PRIORITY)); base::WeakPtr<SpdyStream> streams[] = { stream1->GetWeakPtr(), stream2->GetWeakPtr(), stream3->GetWeakPtr(), stream4->GetWeakPtr() @@ -241,7 +246,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) { for (int i = 0; i < 100; i += arraysize(streams)) { SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; ASSERT_TRUE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)) << "Unable to Dequeue i: " << i; @@ -251,7 +256,7 @@ TEST_F(SpdyWriteQueueTest, RemovePendingWritesForStreamsAfter) { } SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); } @@ -270,7 +275,7 @@ TEST_F(SpdyWriteQueueTest, Clear) { write_queue.Clear(); SpdyFrameType frame_type = DATA; - scoped_ptr<SpdyBufferProducer> frame_producer; + std::unique_ptr<SpdyBufferProducer> frame_producer; base::WeakPtr<SpdyStream> stream; EXPECT_FALSE(write_queue.Dequeue(&frame_type, &frame_producer, &stream)); } @@ -278,13 +283,12 @@ TEST_F(SpdyWriteQueueTest, Clear) { TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { SpdyWriteQueue queue; queue.Enqueue( - DEFAULT_PRIORITY, - SYN_STREAM, - scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), + DEFAULT_PRIORITY, SYN_STREAM, + std::unique_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), base::WeakPtr<SpdyStream>()); { SpdyFrameType frame_type; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); @@ -295,7 +299,7 @@ TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { EXPECT_FALSE(queue.IsEmpty()); SpdyFrameType frame_type; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); @@ -305,16 +309,15 @@ TEST_F(SpdyWriteQueueTest, RequeingProducerWithoutReentrance) { TEST_F(SpdyWriteQueueTest, ReentranceOnClear) { SpdyWriteQueue queue; queue.Enqueue( - DEFAULT_PRIORITY, - SYN_STREAM, - scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), + DEFAULT_PRIORITY, SYN_STREAM, + std::unique_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), base::WeakPtr<SpdyStream>()); queue.Clear(); EXPECT_FALSE(queue.IsEmpty()); SpdyFrameType frame_type; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> stream; EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &stream)); @@ -322,21 +325,20 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnClear) { } TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) { - scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); stream->set_stream_id(2); SpdyWriteQueue queue; queue.Enqueue( - DEFAULT_PRIORITY, - SYN_STREAM, - scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), + DEFAULT_PRIORITY, SYN_STREAM, + std::unique_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), stream->GetWeakPtr()); queue.RemovePendingWritesForStreamsAfter(1); EXPECT_FALSE(queue.IsEmpty()); SpdyFrameType frame_type; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> weak_stream; EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); @@ -344,21 +346,20 @@ TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesAfter) { } TEST_F(SpdyWriteQueueTest, ReentranceOnRemovePendingWritesForStream) { - scoped_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); + std::unique_ptr<SpdyStream> stream(MakeTestStream(DEFAULT_PRIORITY)); stream->set_stream_id(2); SpdyWriteQueue queue; queue.Enqueue( - DEFAULT_PRIORITY, - SYN_STREAM, - scoped_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), + DEFAULT_PRIORITY, SYN_STREAM, + std::unique_ptr<SpdyBufferProducer>(new RequeingBufferProducer(&queue)), stream->GetWeakPtr()); queue.RemovePendingWritesForStream(stream->GetWeakPtr()); EXPECT_FALSE(queue.IsEmpty()); SpdyFrameType frame_type; - scoped_ptr<SpdyBufferProducer> producer; + std::unique_ptr<SpdyBufferProducer> producer; base::WeakPtr<SpdyStream> weak_stream; EXPECT_TRUE(queue.Dequeue(&frame_type, &producer, &weak_stream)); diff --git a/chromium/net/spdy/write_blocked_list.h b/chromium/net/spdy/write_blocked_list.h index 76d22da257a..c7d278eadef 100644 --- a/chromium/net/spdy/write_blocked_list.h +++ b/chromium/net/spdy/write_blocked_list.h @@ -9,9 +9,10 @@ #include <algorithm> #include <deque> +#include <unordered_map> -#include "base/containers/hash_tables.h" #include "base/logging.h" +#include "net/spdy/spdy_bug_tracker.h" #include "net/spdy/spdy_protocol.h" namespace net { @@ -31,11 +32,11 @@ class WriteBlockedList { static SpdyPriority ClampPriority(SpdyPriority priority) { if (priority < kV3HighestPriority) { - LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); + SPDY_BUG << "Invalid priority: " << static_cast<int>(priority); return kV3HighestPriority; } if (priority > kV3LowestPriority) { - LOG(DFATAL) << "Invalid priority: " << static_cast<int>(priority); + SPDY_BUG << "Invalid priority: " << static_cast<int>(priority); return kV3LowestPriority; } return priority; @@ -48,7 +49,7 @@ class WriteBlockedList { return i; } } - LOG(DFATAL) << "No blocked streams"; + SPDY_BUG << "No blocked streams"; return kV3HighestPriority; } @@ -151,7 +152,7 @@ class WriteBlockedList { private: friend class net::test::WriteBlockedListPeer; - typedef base::hash_map<IdType, SpdyPriority> StreamToPriorityMap; + using StreamToPriorityMap = std::unordered_map<IdType, SpdyPriority>; void AddStream(IdType stream_id, SpdyPriority priority, bool push_back) { priority = ClampPriority(priority); diff --git a/chromium/net/spdy/write_scheduler.cc b/chromium/net/spdy/write_scheduler.cc new file mode 100644 index 00000000000..2a7e64b2726 --- /dev/null +++ b/chromium/net/spdy/write_scheduler.cc @@ -0,0 +1,49 @@ +// Copyright (c) 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/spdy/write_scheduler.h" + +#include "base/logging.h" +#include "net/spdy/spdy_bug_tracker.h" +#include "net/spdy/spdy_protocol.h" + +namespace net { + +SpdyPriority ClampSpdyPriority(SpdyPriority priority) { + if (priority < kV3HighestPriority) { + SPDY_BUG << "Invalid priority: " << static_cast<int>(priority); + return kV3HighestPriority; + } + if (priority > kV3LowestPriority) { + SPDY_BUG << "Invalid priority: " << static_cast<int>(priority); + return kV3LowestPriority; + } + return priority; +} + +int ClampHttp2Weight(int weight) { + if (weight < kHttp2MinStreamWeight) { + SPDY_BUG << "Invalid weight: " << weight; + return kHttp2MinStreamWeight; + } + if (weight > kHttp2MaxStreamWeight) { + SPDY_BUG << "Invalid weight: " << weight; + return kHttp2MaxStreamWeight; + } + return weight; +} + +int SpdyPriorityToHttp2Weight(SpdyPriority priority) { + priority = ClampSpdyPriority(priority); + const float kSteps = 255.9f / 7.f; + return static_cast<int>(kSteps * (7.f - priority)) + 1; +} + +SpdyPriority Http2WeightToSpdyPriority(int weight) { + weight = ClampHttp2Weight(weight); + const float kSteps = 255.9f / 7.f; + return static_cast<SpdyPriority>(7.f - (weight - 1) / kSteps); +} + +} // namespace net diff --git a/chromium/net/spdy/write_scheduler.h b/chromium/net/spdy/write_scheduler.h new file mode 100644 index 00000000000..4538e1f08eb --- /dev/null +++ b/chromium/net/spdy/write_scheduler.h @@ -0,0 +1,185 @@ +// Copyright (c) 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. + +#ifndef NET_SPDY_WRITE_SCHEDULER_H_ +#define NET_SPDY_WRITE_SCHEDULER_H_ + +#include <vector> + +#include "net/spdy/spdy_protocol.h" + +namespace net { + +// Abstract superclass for classes that decide which SPDY or HTTP/2 stream to +// write next. Concrete subclasses implement various scheduling policies: +// +// PriorityWriteScheduler: implements SPDY priority-based stream scheduling, +// where (writable) higher-priority streams are always given precedence +// over lower-priority streams. +// +// Http2PriorityWriteScheduler: implements SPDY priority-based stream +// scheduling coupled with the HTTP/2 stream dependency model. This is only +// intended as a transitional step towards Http2WeightedWriteScheduler. +// +// Http2WeightedWriteScheduler (coming soon): implements the HTTP/2 stream +// dependency model with weighted stream scheduling, fully conforming to +// RFC 7540. +// +// The type used to represent stream IDs (StreamIdType) is templated in order +// to allow for use by both SPDY and QUIC codebases. It must be a POD that +// supports comparison (i.e., a numeric type). +// +// Each stream can be in one of two states: ready or not ready (for writing). +// Ready state is changed by calling the MarkStreamReady() and +// MarkStreamNotReady() methods. Only streams in the ready state can be +// returned by PopNextReadyStream(); when returned by that method, the stream's +// state changes to not ready. +template <typename StreamIdType> +class NET_EXPORT_PRIVATE WriteScheduler { + public: + virtual ~WriteScheduler() {} + + // Registers new stream |stream_id| with the scheduler, assigning it the + // given weight, which should be in the range [1, 256]. If the scheduler + // supports stream dependencies, the stream is inserted into the dependency + // tree under the specified parent stream. + // + // Preconditions: |stream_id| should be unregistered, and |parent_id| should + // be registered or |kHttp2RootStreamId|. + virtual void RegisterStream(StreamIdType stream_id, + StreamIdType parent_id, + int weight, + bool exclusive) = 0; + + // Registers a new stream with the scheduler, assigning it the given + // priority. + // + // Preconditions: |stream_id| should be unregistered. + virtual void RegisterStream(StreamIdType stream_id, + SpdyPriority priority) = 0; + + // Unregisters the given stream from the scheduler, which will no longer keep + // state for it. + // + // Preconditions: |stream_id| should be registered. + virtual void UnregisterStream(StreamIdType stream_id) = 0; + + // Returns true if the given stream is currently registered. + virtual bool StreamRegistered(StreamIdType stream_id) const = 0; + + // Returns the priority value for the specified stream. If the scheduler uses + // weights rather than priorities, the returned value is the stream's weight + // mapped to a SPDY priority. + // + // Preconditions: |stream_id| should be registered. + virtual SpdyPriority GetStreamPriority(StreamIdType stream_id) const = 0; + + // Updates the priority of the given stream. + // + // Preconditions: |stream_id| should be registered. + virtual void UpdateStreamPriority(StreamIdType stream_id, + SpdyPriority priority) = 0; + + // Returns the weight value for the specified stream. If the scheduler uses + // SPDY priorities rather than weights, the returned value is the stream's + // SPDY priority mapped to a weight. + // + // Preconditions: |stream_id| should be registered. + virtual int GetStreamWeight(StreamIdType stream_id) const = 0; + + // Updates the weight of the given stream. + // + // Preconditions: |stream_id| should be registered. + virtual void UpdateStreamWeight(StreamIdType stream_id, int weight) = 0; + + // Returns the parent stream of |stream_id|. If the scheduler + // doesn't support stream dependencies, returns |kHttp2RootStreamId|. + // + // Preconditions: |stream_id| should be registered. + virtual StreamIdType GetStreamParent(StreamIdType stream_id) const = 0; + + // Updates which stream is the parent stream of |stream_id|. If the scheduler + // doesn't support stream dependencies of the stream, does nothing. + // + // Preconditions: |stream_id| should be registered. + virtual void UpdateStreamParent(StreamIdType stream_id, + StreamIdType parent_id, + bool exclusive) = 0; + + // Returns child streams of the given stream, if any. If the scheduler + // doesn't support stream dependencies, returns an empty vector. + // + // Preconditions: |stream_id| should be registered. + virtual std::vector<StreamIdType> GetStreamChildren( + StreamIdType stream_id) const = 0; + + // Records time (in microseconds) of a read/write event for the given + // stream. + // + // Preconditions: |stream_id| should be registered. + virtual void RecordStreamEventTime(StreamIdType stream_id, + int64_t now_in_usec) = 0; + + // Returns time (in microseconds) of the last read/write event for a stream + // with higher priority than the priority of the given stream, or 0 if there + // is no such event. + // + // Preconditions: |stream_id| should be registered. + virtual int64_t GetLatestEventWithPrecedence( + StreamIdType stream_id) const = 0; + + // If the scheduler has any ready streams, returns the next scheduled + // ready stream, in the process transitioning the stream from ready to not + // ready. + // + // Preconditions: |HasReadyStreams() == true| + virtual StreamIdType PopNextReadyStream() = 0; + + // Returns true if there's another stream ahead of the given stream in the + // scheduling queue. This function can be called to see if the given stream + // should yield work to another stream. + // + // Preconditions: |stream_id| should be registered. + virtual bool ShouldYield(StreamIdType stream_id) const = 0; + + // Marks the stream as ready to write. If the stream was already ready, does + // nothing. If add_to_front is true, the stream is scheduled ahead of other + // streams of the same priority/weight, otherwise it is scheduled behind them. + // + // Preconditions: |stream_id| should be registered. + virtual void MarkStreamReady(StreamIdType stream_id, bool add_to_front) = 0; + + // Marks the stream as not ready to write. If the stream is not registered or + // not ready, does nothing. + // + // Preconditions: |stream_id| should be registered. + virtual void MarkStreamNotReady(StreamIdType stream_id) = 0; + + // Returns true iff the scheduler has any ready streams. + virtual bool HasReadyStreams() const = 0; + + // Returns the number of streams currently marked ready. + virtual size_t NumReadyStreams() const = 0; +}; + +// Returns SPDY priority value clamped to the valid range of [0, 7]. +NET_EXPORT_PRIVATE SpdyPriority ClampSpdyPriority(SpdyPriority priority); + +// Returns HTTP/2 weight clamped to the valid range of [1, 256]. +NET_EXPORT_PRIVATE int ClampHttp2Weight(int weight); + +// Maps SPDY priority value in range [0, 7] to HTTP/2 weight value in range +// [1, 256], where priority 0 (i.e. highest precedence) corresponds to maximum +// weight 256 and priority 7 (lowest precedence) corresponds to minimum weight +// 1. +NET_EXPORT_PRIVATE int SpdyPriorityToHttp2Weight(SpdyPriority priority); + +// Maps HTTP/2 weight value in range [1, 256] to SPDY priority value in range +// [0, 7], where minimum weight 1 corresponds to priority 7 (lowest precedence) +// and maximum weight 256 corresponds to priority 0 (highest precedence). +NET_EXPORT_PRIVATE SpdyPriority Http2WeightToSpdyPriority(int weight); + +} // namespace net + +#endif // NET_SPDY_WRITE_SCHEDULER_H_ diff --git a/chromium/net/spdy/write_scheduler_test.cc b/chromium/net/spdy/write_scheduler_test.cc new file mode 100644 index 00000000000..957495410db --- /dev/null +++ b/chromium/net/spdy/write_scheduler_test.cc @@ -0,0 +1,59 @@ +// Copyright (c) 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/spdy/write_scheduler.h" + +#include "net/spdy/spdy_test_utils.h" +#include "testing/gtest/include/gtest/gtest.h" + +namespace net { + +namespace test { + +TEST(WriteSchedulerTest, ClampSpdyPriority) { + EXPECT_SPDY_BUG(EXPECT_EQ(7, ClampSpdyPriority(8)), "Invalid priority: 8"); + EXPECT_EQ(kV3LowestPriority, ClampSpdyPriority(kV3LowestPriority)); + EXPECT_EQ(kV3HighestPriority, ClampSpdyPriority(kV3HighestPriority)); +} + +TEST(WriteSchedulerTest, ClampHttp2Weight) { + EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(0)), + "Invalid weight: 0"); + EXPECT_SPDY_BUG(EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(300)), + "Invalid weight: 300"); + EXPECT_EQ(kHttp2MinStreamWeight, ClampHttp2Weight(kHttp2MinStreamWeight)); + EXPECT_EQ(kHttp2MaxStreamWeight, ClampHttp2Weight(kHttp2MaxStreamWeight)); +} + +TEST(WriteSchedulerTest, SpdyPriorityToHttp2Weight) { + EXPECT_EQ(256, SpdyPriorityToHttp2Weight(0)); + EXPECT_EQ(220, SpdyPriorityToHttp2Weight(1)); + EXPECT_EQ(183, SpdyPriorityToHttp2Weight(2)); + EXPECT_EQ(147, SpdyPriorityToHttp2Weight(3)); + EXPECT_EQ(110, SpdyPriorityToHttp2Weight(4)); + EXPECT_EQ(74, SpdyPriorityToHttp2Weight(5)); + EXPECT_EQ(37, SpdyPriorityToHttp2Weight(6)); + EXPECT_EQ(1, SpdyPriorityToHttp2Weight(7)); +} + +TEST(WriteSchedulerTest, Http2WeightToSpdyPriority) { + EXPECT_EQ(0u, Http2WeightToSpdyPriority(256)); + EXPECT_EQ(0u, Http2WeightToSpdyPriority(221)); + EXPECT_EQ(1u, Http2WeightToSpdyPriority(220)); + EXPECT_EQ(1u, Http2WeightToSpdyPriority(184)); + EXPECT_EQ(2u, Http2WeightToSpdyPriority(183)); + EXPECT_EQ(2u, Http2WeightToSpdyPriority(148)); + EXPECT_EQ(3u, Http2WeightToSpdyPriority(147)); + EXPECT_EQ(3u, Http2WeightToSpdyPriority(111)); + EXPECT_EQ(4u, Http2WeightToSpdyPriority(110)); + EXPECT_EQ(4u, Http2WeightToSpdyPriority(75)); + EXPECT_EQ(5u, Http2WeightToSpdyPriority(74)); + EXPECT_EQ(5u, Http2WeightToSpdyPriority(38)); + EXPECT_EQ(6u, Http2WeightToSpdyPriority(37)); + EXPECT_EQ(6u, Http2WeightToSpdyPriority(2)); + EXPECT_EQ(7u, Http2WeightToSpdyPriority(1)); +} + +} // namespace test +} // namespace net |