Index: net/spdy/hpack/hpack_decoder.cc |
diff --git a/net/spdy/hpack/hpack_decoder.cc b/net/spdy/hpack/hpack_decoder.cc |
deleted file mode 100644 |
index 611e2c5c855ae446a5e9a206e633262ef34719ae..0000000000000000000000000000000000000000 |
--- a/net/spdy/hpack/hpack_decoder.cc |
+++ /dev/null |
@@ -1,285 +0,0 @@ |
-// Copyright 2014 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/hpack/hpack_decoder.h" |
- |
-#include <utility> |
- |
-#include "base/logging.h" |
-#include "net/spdy/hpack/hpack_constants.h" |
-#include "net/spdy/hpack/hpack_entry.h" |
-#include "net/spdy/platform/api/spdy_estimate_memory_usage.h" |
-#include "net/spdy/spdy_flags.h" |
- |
-namespace net { |
- |
-HpackDecoder::HpackDecoder() |
- : handler_(nullptr), |
- total_header_bytes_(0), |
- total_parsed_bytes_(0), |
- header_block_started_(false), |
- size_updates_seen_(0), |
- size_updates_allowed_(true), |
- incremental_decode_(false) {} |
- |
-HpackDecoder::~HpackDecoder() {} |
- |
-void HpackDecoder::ApplyHeaderTableSizeSetting(size_t size_setting) { |
- header_table_.SetSettingsHeaderTableSize(size_setting); |
-} |
- |
-void HpackDecoder::HandleControlFrameHeadersStart( |
- SpdyHeadersHandlerInterface* handler) { |
- handler_ = handler; |
- total_header_bytes_ = 0; |
-} |
- |
-bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data, |
- size_t headers_data_length) { |
- if (!header_block_started_) { |
- decoded_block_.clear(); |
- header_block_started_ = true; |
- size_updates_allowed_ = true; |
- size_updates_seen_ = 0; |
- if (handler_ != nullptr) { |
- handler_->OnHeaderBlockStart(); |
- } |
- } |
- size_t new_size = headers_block_buffer_.size() + headers_data_length; |
- if (max_decode_buffer_size_bytes_ > 0 && |
- new_size > max_decode_buffer_size_bytes_) { |
- DVLOG(1) << "max_decode_buffer_size_bytes_ < new_size: " |
- << max_decode_buffer_size_bytes_ << " < " << new_size; |
- return false; |
- } |
- headers_block_buffer_.insert(headers_block_buffer_.end(), headers_data, |
- headers_data + headers_data_length); |
- |
- // Parse as many whole HPACK entries in the buffer as possible, |
- // and then remove the parsed data from the buffer. |
- HpackInputStream input_stream(headers_block_buffer_); |
- while (input_stream.HasMoreData()) { |
- if (!DecodeNextOpcodeWrapper(&input_stream)) { |
- if (input_stream.NeedMoreData()) { |
- break; |
- } |
- DVLOG(1) << "!DecodeNextOpcodeWrapper"; |
- 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) { |
- 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) { |
- DVLOG(1) << "headers_block_buffer_.size() should be zero, but is " |
- << headers_block_buffer_.size(); |
- return false; |
- } |
- |
- if (handler_ != nullptr) { |
- if (FLAGS_chromium_http2_flag_log_compressed_size) { |
- handler_->OnHeaderBlockEnd(total_header_bytes_, total_parsed_bytes_); |
- } else { |
- handler_->OnHeaderBlockEnd(total_header_bytes_); |
- } |
- } |
- headers_block_buffer_.clear(); |
- total_parsed_bytes_ = 0; |
- header_block_started_ = false; |
- handler_ = nullptr; |
- return true; |
-} |
- |
-const SpdyHeaderBlock& HpackDecoder::decoded_block() const { |
- return decoded_block_; |
-} |
- |
-void HpackDecoder::SetHeaderTableDebugVisitor( |
- std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { |
- header_table_.set_debug_visitor(std::move(visitor)); |
-} |
- |
-void HpackDecoder::set_max_decode_buffer_size_bytes( |
- size_t max_decode_buffer_size_bytes) { |
- max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes; |
-} |
- |
-size_t HpackDecoder::EstimateMemoryUsage() const { |
- return SpdyEstimateMemoryUsage(header_table_) + |
- SpdyEstimateMemoryUsage(headers_block_buffer_) + |
- SpdyEstimateMemoryUsage(decoded_block_) + |
- SpdyEstimateMemoryUsage(key_buffer_) + |
- SpdyEstimateMemoryUsage(value_buffer_); |
-} |
- |
-bool HpackDecoder::HandleHeaderRepresentation(SpdyStringPiece name, |
- SpdyStringPiece value) { |
- size_updates_allowed_ = false; |
- total_header_bytes_ += name.size() + value.size(); |
- |
- if (handler_ == nullptr) { |
- decoded_block_.AppendValueOrAddHeader(name, value); |
- } else { |
- DCHECK(decoded_block_.empty()); |
- handler_->OnHeader(name, value); |
- } |
- 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)) { |
- return DecodeNextIndexedHeader(input_stream); |
- } |
- // Implements 7.2.1: Literal Header Field with Incremental Indexing. |
- if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { |
- return DecodeNextLiteralHeader(input_stream, true); |
- } |
- // Implements 7.2.2: Literal Header Field without Indexing. |
- if (input_stream->MatchPrefixAndConsume(kLiteralNoIndexOpcode)) { |
- return DecodeNextLiteralHeader(input_stream, false); |
- } |
- // Implements 7.2.3: Literal Header Field never Indexed. |
- // TODO(jgraettinger): Preserve the never-indexed bit. |
- if (input_stream->MatchPrefixAndConsume(kLiteralNeverIndexOpcode)) { |
- return DecodeNextLiteralHeader(input_stream, false); |
- } |
- // Implements 7.3: Header Table Size Update. |
- if (input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) { |
- // Header table size updates cannot appear mid-block. |
- return DecodeNextHeaderTableSizeUpdate(input_stream); |
- } |
- // Unrecognized opcode. |
- return false; |
-} |
- |
-bool HpackDecoder::DecodeNextHeaderTableSizeUpdate( |
- HpackInputStream* input_stream) { |
- uint32_t size = 0; |
- if (!input_stream->DecodeNextUint32(&size)) { |
- return false; |
- } |
- if (!size_updates_allowed_) { |
- DVLOG(1) << "Size updates not allowed after header entries."; |
- return false; |
- } |
- ++size_updates_seen_; |
- if (size_updates_seen_ > 2) { |
- DVLOG(1) << "Too many size updates at the start of the block."; |
- return false; |
- } |
- if (size > header_table_.settings_size_bound()) { |
- DVLOG(1) << "Size (" << size << ") exceeds SETTINGS limit (" |
- << header_table_.settings_size_bound() << ")"; |
- return false; |
- } |
- header_table_.SetMaxSize(size); |
- return true; |
-} |
- |
-bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) { |
- uint32_t index = 0; |
- if (!input_stream->DecodeNextUint32(&index)) { |
- return false; |
- } |
- |
- const HpackEntry* entry = header_table_.GetByIndex(index); |
- if (entry == NULL) { |
- DVLOG(1) << "Index " << index << " is not valid."; |
- return false; |
- } |
- |
- return HandleHeaderRepresentation(entry->name(), entry->value()); |
-} |
- |
-bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream, |
- bool should_index) { |
- SpdyStringPiece name; |
- if (!DecodeNextName(input_stream, &name)) { |
- return false; |
- } |
- |
- SpdyStringPiece value; |
- if (!DecodeNextStringLiteral(input_stream, false, &value)) { |
- return false; |
- } |
- |
- if (!HandleHeaderRepresentation(name, value)) { |
- return false; |
- } |
- |
- if (!should_index) { |
- return true; |
- } |
- |
- ignore_result(header_table_.TryAddEntry(name, value)); |
- return true; |
-} |
- |
-bool HpackDecoder::DecodeNextName(HpackInputStream* input_stream, |
- SpdyStringPiece* next_name) { |
- uint32_t index_or_zero = 0; |
- if (!input_stream->DecodeNextUint32(&index_or_zero)) { |
- DVLOG(1) << "Failed to decode the next uint."; |
- return false; |
- } |
- |
- if (index_or_zero == 0) { |
- return DecodeNextStringLiteral(input_stream, true, next_name); |
- } |
- |
- const HpackEntry* entry = header_table_.GetByIndex(index_or_zero); |
- if (entry == NULL) { |
- DVLOG(1) << "index " << index_or_zero << " is not valid."; |
- return false; |
- } |
- if (entry->IsStatic()) { |
- *next_name = entry->name(); |
- } else { |
- // |entry| could be evicted as part of this insertion. Preemptively copy. |
- key_buffer_.assign(entry->name().data(), entry->name().size()); |
- *next_name = key_buffer_; |
- } |
- return true; |
-} |
- |
-bool HpackDecoder::DecodeNextStringLiteral(HpackInputStream* input_stream, |
- bool is_key, |
- SpdyStringPiece* output) { |
- if (input_stream->MatchPrefixAndConsume(kStringLiteralHuffmanEncoded)) { |
- SpdyString* buffer = is_key ? &key_buffer_ : &value_buffer_; |
- bool result = input_stream->DecodeNextHuffmanString(buffer); |
- *output = SpdyStringPiece(*buffer); |
- return result; |
- } else if (input_stream->MatchPrefixAndConsume( |
- kStringLiteralIdentityEncoded)) { |
- return input_stream->DecodeNextIdentityString(output); |
- } else { |
- DVLOG(1) << "String literal is neither Huffman nor identity encoded!"; |
- return false; |
- } |
-} |
- |
-} // namespace net |