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..0f90c20b1e23c8a35a37bae5aacd31bea25c63e9 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,11 @@ 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_)); |
+ header_buffer_.clear(); |
Ryan Hamilton
2016/01/08 00:16:29
Does this do anything since the buffer was newly c
Bence
2016/01/08 18:58:24
Hm, I guess not. Thanks for catching it.
|
} |
BufferedSpdyFramer::~BufferedSpdyFramer() { |
@@ -127,8 +130,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 +174,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); |
Ryan Hamilton
2016/01/08 00:16:29
Can new_size ever be < kHeaderBufferInitialSize, s
Bence
2016/01/08 18:58:24
Yes, new_size can be smaller. This is the only pl
Ryan Hamilton
2016/01/08 21:20:46
Hah, I missed that. Good point :>
|
+ 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; |
Ryan Hamilton
2016/01/08 00:16:29
Should we have a unit test of this new behavior?
Bence
2016/01/08 18:58:24
The behavior of larger buffer limit? There is one
|
} |
@@ -442,8 +452,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); |