| Index: net/spdy/buffered_spdy_framer.cc
|
| diff --git a/net/spdy/buffered_spdy_framer.cc b/net/spdy/buffered_spdy_framer.cc
|
| index 2372aff1a56ce65f05df688c7a87bf410fcd66b6..d136d1df4224af762d6fdcc0ede544ccacffc4df 100644
|
| --- a/net/spdy/buffered_spdy_framer.cc
|
| +++ b/net/spdy/buffered_spdy_framer.cc
|
| @@ -13,6 +13,10 @@ namespace {
|
| // GOAWAY frame debug data is only buffered up to this many bytes.
|
| size_t kGoAwayDebugDataMaxSize = 1024;
|
|
|
| +// Initial and maximum sizes for header block buffer.
|
| +size_t kHeaderBufferInitialSize = 8 * 1024;
|
| +size_t kHeaderBufferMaxSize = 256 * 1024;
|
| +
|
| } // namespace
|
|
|
| SpdyMajorVersion NextProtoToSpdyMajorVersion(NextProto next_proto) {
|
| @@ -37,12 +41,10 @@ BufferedSpdyFramer::BufferedSpdyFramer(SpdyMajorVersion version,
|
| bool enable_compression)
|
| : spdy_framer_(version),
|
| visitor_(NULL),
|
| - header_buffer_used_(0),
|
| header_buffer_valid_(false),
|
| header_stream_id_(SpdyFramer::kInvalidStream),
|
| frames_received_(0) {
|
| spdy_framer_.set_enable_compression(enable_compression);
|
| - memset(header_buffer_, 0, sizeof(header_buffer_));
|
| }
|
|
|
| BufferedSpdyFramer::~BufferedSpdyFramer() {
|
| @@ -127,8 +129,8 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
|
| CHECK(header_buffer_valid_);
|
|
|
| SpdyHeaderBlock headers;
|
| - if (!spdy_framer_.ParseHeaderBlockInBuffer(header_buffer_,
|
| - header_buffer_used_, &headers)) {
|
| + if (!spdy_framer_.ParseHeaderBlockInBuffer(
|
| + header_buffer_.data(), header_buffer_.size(), &headers)) {
|
| visitor_->OnStreamError(
|
| stream_id, "Could not parse Spdy Control Frame Header.");
|
| return false;
|
| @@ -171,15 +173,22 @@ bool BufferedSpdyFramer::OnControlFrameHeaderData(SpdyStreamId stream_id,
|
| return true;
|
| }
|
|
|
| - const size_t available = kHeaderBufferSize - header_buffer_used_;
|
| - if (len > available) {
|
| + const size_t new_size = header_buffer_.size() + len;
|
| + if (new_size > kHeaderBufferMaxSize) {
|
| header_buffer_valid_ = false;
|
| - visitor_->OnStreamError(
|
| - stream_id, "Received more data than the allocated size.");
|
| + visitor_->OnStreamError(stream_id, "Received too much header data.");
|
| return false;
|
| }
|
| - memcpy(header_buffer_ + header_buffer_used_, header_data, len);
|
| - header_buffer_used_ += len;
|
| +
|
| + if (new_size > header_buffer_.capacity()) {
|
| + // Grow |header_buffer_| exponentially to reduce memory allocations and
|
| + // copies.
|
| + size_t new_capacity = std::max(new_size, kHeaderBufferInitialSize);
|
| + new_capacity = std::max(new_capacity, 2 * header_buffer_.capacity());
|
| + new_capacity = std::min(new_capacity, kHeaderBufferMaxSize);
|
| + header_buffer_.reserve(new_capacity);
|
| + }
|
| + header_buffer_.append(header_data, len);
|
| return true;
|
| }
|
|
|
| @@ -442,8 +451,7 @@ SpdyPriority BufferedSpdyFramer::GetHighestPriority() const {
|
| }
|
|
|
| void BufferedSpdyFramer::InitHeaderStreaming(SpdyStreamId stream_id) {
|
| - memset(header_buffer_, 0, kHeaderBufferSize);
|
| - header_buffer_used_ = 0;
|
| + header_buffer_.clear();
|
| header_buffer_valid_ = true;
|
| header_stream_id_ = stream_id;
|
| DCHECK_NE(header_stream_id_, SpdyFramer::kInvalidStream);
|
|
|