| Index: net/spdy/hpack/hpack_decoder.cc
|
| diff --git a/net/spdy/hpack/hpack_decoder.cc b/net/spdy/hpack/hpack_decoder.cc
|
| index 6d4ab9896d771835f5b7a97b94556d1824957166..6e961faf5e283726761b39c405e7466a96d48be7 100644
|
| --- a/net/spdy/hpack/hpack_decoder.cc
|
| +++ b/net/spdy/hpack/hpack_decoder.cc
|
| @@ -26,15 +26,16 @@ 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 +46,44 @@ 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();
|
| - }
|
| 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;
|
| + 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 +123,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)) {
|
|
|