Index: net/spdy/hpack/hpack_decoder2.cc |
diff --git a/net/spdy/hpack/hpack_decoder2.cc b/net/spdy/hpack/hpack_decoder2.cc |
deleted file mode 100644 |
index 14ff94e990f38afd6bee7c271f251cf73c5c81a7..0000000000000000000000000000000000000000 |
--- a/net/spdy/hpack/hpack_decoder2.cc |
+++ /dev/null |
@@ -1,337 +0,0 @@ |
-// 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/hpack/hpack_decoder2.h" |
- |
-#include <list> |
-#include <utility> |
- |
-#include "base/logging.h" |
-#include "base/strings/string_piece.h" |
-#include "net/http2/decoder/decode_buffer.h" |
-#include "net/http2/decoder/decode_status.h" |
-#include "net/spdy/hpack/hpack_entry.h" |
-#include "net/spdy/platform/api/spdy_estimate_memory_usage.h" |
- |
-using base::StringPiece; |
- |
-namespace net { |
- |
-HpackDecoder2::HpackDecoder2() : hpack_block_decoder_(this) { |
- Reset(); |
-} |
- |
-HpackDecoder2::~HpackDecoder2() {} |
- |
-void HpackDecoder2::Reset() { |
- DVLOG(2) << "HpackDecoder2::Reset"; |
- handler_ = nullptr; |
- |
- hpack_block_decoder_.Reset(); |
- hpack_block_decoder_.set_listener(this); |
- |
- total_hpack_bytes_ = 0; |
- total_header_bytes_ = 0; |
- size_update_count_ = 0; |
- header_seen_ = false; |
- in_progress_ = false; |
- error_detected_ = false; |
- header_block_started_ = false; |
- |
- name_.Reset(); |
- value_.Reset(); |
-} |
- |
-void HpackDecoder2::SetErrorDetected() { |
- if (!error_detected_) { |
- DVLOG(2) << "HpackDecoder2::SetErrorDetected"; |
- hpack_block_decoder_.set_listener(&no_op_listener_); |
- error_detected_ = true; |
- } |
-} |
- |
-void HpackDecoder2::ApplyHeaderTableSizeSetting(size_t size_setting) { |
- DVLOG(2) << "HpackDecoder2::ApplyHeaderTableSizeSetting"; |
- header_table_.SetSettingsHeaderTableSize(size_setting); |
-} |
- |
-// If a SpdyHeadersHandlerInterface is provided, the decoder will emit |
-// headers to it rather than accumulating them in a SpdyHeaderBlock. |
-void HpackDecoder2::HandleControlFrameHeadersStart( |
- SpdyHeadersHandlerInterface* handler) { |
- DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersStart"; |
- DCHECK(!header_block_started_); |
- handler_ = handler; |
-} |
- |
-// Called as HPACK block fragments arrive. Returns false |
-// if an error occurred while decoding the block. |
-bool HpackDecoder2::HandleControlFrameHeadersData(const char* headers_data, |
- size_t headers_data_length) { |
- DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersData: len=" |
- << headers_data_length; |
- if (!header_block_started_) { |
- DCHECK_EQ(total_hpack_bytes_, 0u); |
- // Clear the SpdyHeaderBlock here rather than in Reset so that it is NOT |
- // cleared in HandleControlFrameHeadersComplete, which would be before it |
- // could be used. |
- decoded_block_.clear(); |
- header_block_started_ = true; |
- if (handler_ != nullptr) { |
- handler_->OnHeaderBlockStart(); |
- } |
- } |
- |
- // Sometimes we get a call with headers_data==nullptr and |
- // headers_data_length==0, in which case we need to avoid creating |
- // a DecodeBuffer, which would otherwise complain. |
- if (headers_data_length > 0) { |
- DCHECK_NE(headers_data, nullptr); |
- total_hpack_bytes_ += headers_data_length; |
- DecodeBuffer db(headers_data, headers_data_length); |
- DecodeStatus status = hpack_block_decoder_.Decode(&db); |
- switch (status) { |
- case DecodeStatus::kDecodeDone: |
- // We've completed the decoding of headers_data, and it ended at the |
- // boundary between two HPACK block entries, so name_ and value_ are |
- // currently reset. |
- DCHECK_EQ(0u, db.Remaining()); |
- in_progress_ = false; |
- break; |
- |
- case DecodeStatus::kDecodeInProgress: |
- DCHECK_EQ(0u, db.Remaining()); |
- in_progress_ = true; |
- if (!error_detected_) { |
- name_.BufferStringIfUnbuffered(); |
- value_.BufferStringIfUnbuffered(); |
- EnforceMaxDecodeBufferSize(); |
- } |
- break; |
- |
- case DecodeStatus::kDecodeError: |
- SetErrorDetected(); |
- break; |
- } |
- } |
- return !error_detected_; |
-} |
- |
-// Called after a HPACK block has been completely delivered via |
-// HandleControlFrameHeadersData(). Returns false if an error occurred. |
-// |compressed_len| if non-null will be set to the size of the encoded |
-// buffered block that was accumulated in HandleControlFrameHeadersData(), |
-// to support subsequent calculation of compression percentage. |
-// Discards the handler supplied at the start of decoding the block. |
-// TODO(jamessynge): Determine if compressed_len is needed; it is used to |
-// produce UUMA stat Net.SpdyHpackDecompressionPercentage, but only for |
-// SPDY3, not HTTP2. |
-bool HpackDecoder2::HandleControlFrameHeadersComplete(size_t* compressed_len) { |
- DVLOG(2) << "HpackDecoder2::HandleControlFrameHeadersComplete"; |
- if (error_detected_ || in_progress_) { |
- DVLOG(2) << "error_detected_=" << error_detected_ |
- << ", in_progress_=" << in_progress_; |
- return false; |
- } |
- if (compressed_len != nullptr) { |
- *compressed_len = total_hpack_bytes_; |
- } |
- if (handler_ != nullptr) { |
- handler_->OnHeaderBlockEnd(total_header_bytes_); |
- } |
- Reset(); |
- return true; |
-} |
- |
-const SpdyHeaderBlock& HpackDecoder2::decoded_block() const { |
- return decoded_block_; |
-} |
- |
-void HpackDecoder2::SetHeaderTableDebugVisitor( |
- std::unique_ptr<HpackHeaderTable::DebugVisitorInterface> visitor) { |
- DVLOG(2) << "HpackDecoder2::SetHeaderTableDebugVisitor"; |
- header_table_.set_debug_visitor(std::move(visitor)); |
-} |
- |
-void HpackDecoder2::set_max_decode_buffer_size_bytes( |
- size_t max_decode_buffer_size_bytes) { |
- DVLOG(2) << "HpackDecoder2::set_max_decode_buffer_size_bytes"; |
- max_decode_buffer_size_bytes_ = max_decode_buffer_size_bytes; |
-} |
- |
-size_t HpackDecoder2::EstimateMemoryUsage() const { |
- return SpdyEstimateMemoryUsage(header_table_) + |
- SpdyEstimateMemoryUsage(decoded_block_) + |
- SpdyEstimateMemoryUsage(name_) + SpdyEstimateMemoryUsage(value_); |
-} |
- |
-void HpackDecoder2::OnIndexedHeader(size_t index) { |
- DVLOG(2) << "HpackDecoder2::OnIndexedHeader: index=" << index; |
- DCHECK(!error_detected_); |
- const HpackEntry* entry = header_table_.GetByIndex(index); |
- if (entry == nullptr) { |
- SetErrorDetected(); |
- return; |
- } |
- HandleHeaderRepresentation(entry->name(), entry->value()); |
-} |
- |
-void HpackDecoder2::OnStartLiteralHeader(HpackEntryType entry_type, |
- size_t maybe_name_index) { |
- DVLOG(2) << "HpackDecoder2::OnStartLiteralHeader: entry_type=" << entry_type |
- << ", maybe_name_index=" << maybe_name_index; |
- DCHECK(!error_detected_); |
- entry_type_ = entry_type; |
- if (maybe_name_index > 0) { |
- const HpackEntry* entry = header_table_.GetByIndex(maybe_name_index); |
- if (entry == nullptr) { |
- SetErrorDetected(); |
- return; |
- } else { |
- // Non-static entries could be evicted, leaving us with a dangling |
- // pointer, so we preemptively copy. This could be avoided if |
- // TryAddEntry would copy the strings prior to performing eviction. |
- name_.Set(entry->name(), entry->IsStatic()); |
- name_.BufferStringIfUnbuffered(); |
- } |
- } |
-} |
- |
-void HpackDecoder2::OnNameStart(bool huffman_encoded, size_t len) { |
- DVLOG(2) << "HpackDecoder2::OnNameStart: huffman_encoded=" |
- << (huffman_encoded ? "true" : "false") << ", len=" << len; |
- if (len > max_decode_buffer_size_bytes_) { |
- DVLOG(1) << "Name length (" << len << ") is longer than permitted (" |
- << max_decode_buffer_size_bytes_ << ")"; |
- SetErrorDetected(); |
- return; |
- } |
- name_.OnStart(huffman_encoded, len); |
-} |
- |
-void HpackDecoder2::OnNameData(const char* data, size_t len) { |
- DVLOG(2) << "HpackDecoder2::OnNameData: len=" << len |
- << "\n data: " << StringPiece(data, len); |
- if (error_detected_) { |
- return; |
- } |
- if (!name_.OnData(data, len)) { |
- SetErrorDetected(); |
- } |
-} |
- |
-void HpackDecoder2::OnNameEnd() { |
- DVLOG(2) << "HpackDecoder2::OnNameEnd"; |
- if (error_detected_) { |
- return; |
- } |
- if (!name_.OnEnd()) { |
- SetErrorDetected(); |
- } |
-} |
- |
-void HpackDecoder2::OnValueStart(bool huffman_encoded, size_t len) { |
- DVLOG(2) << "HpackDecoder2::OnValueStart: huffman_encoded=" |
- << (huffman_encoded ? "true" : "false") << ", len=" << len; |
- if (len > max_decode_buffer_size_bytes_) { |
- DVLOG(1) << "Value length (" << len << ") is longer than permitted (" |
- << max_decode_buffer_size_bytes_ << ")"; |
- SetErrorDetected(); |
- return; |
- } |
- value_.OnStart(huffman_encoded, len); |
-} |
- |
-void HpackDecoder2::OnValueData(const char* data, size_t len) { |
- DVLOG(2) << "HpackDecoder2::OnValueData: len=" << len |
- << "\n data: " << StringPiece(data, len); |
- if (error_detected_) { |
- return; |
- } |
- if (!value_.OnData(data, len)) { |
- SetErrorDetected(); |
- } |
-} |
- |
-void HpackDecoder2::OnValueEnd() { |
- DVLOG(2) << "HpackDecoder2::OnValueEnd"; |
- if (error_detected_) { |
- return; |
- } |
- if (!value_.OnEnd()) { |
- SetErrorDetected(); |
- return; |
- } |
- if (EnforceMaxDecodeBufferSize()) { |
- // All is well. |
- HandleHeaderRepresentation(name_.str(), value_.str()); |
- if (entry_type_ == HpackEntryType::kIndexedLiteralHeader) { |
- header_table_.TryAddEntry(name_.str(), value_.str()); |
- } |
- name_.Reset(); |
- value_.Reset(); |
- } |
-} |
- |
-void HpackDecoder2::OnDynamicTableSizeUpdate(size_t size) { |
- DVLOG(2) << "HpackDecoder2::OnDynamicTableSizeUpdate: size=" << size; |
- if (error_detected_) { |
- return; |
- } |
- if (size > header_table_.settings_size_bound()) { |
- DVLOG(1) << "Dynamic Table Size Update with too large a size: " << size |
- << " > " << header_table_.settings_size_bound(); |
- SetErrorDetected(); |
- return; |
- } |
- if (header_seen_) { |
- DVLOG(1) << "Dynamic Table Size Update seen after a Header"; |
- SetErrorDetected(); |
- return; |
- } |
- ++size_update_count_; |
- if (size_update_count_ > 2) { |
- DVLOG(1) << "Too many (" << size_update_count_ |
- << ") Dynamic Table Size Updates"; |
- SetErrorDetected(); |
- return; |
- } |
- header_table_.SetMaxSize(size); |
- return; |
-} |
- |
-bool HpackDecoder2::EnforceMaxDecodeBufferSize() { |
- if (!error_detected_) { |
- size_t buffered_length = name_.BufferedLength() + value_.BufferedLength(); |
- DVLOG(2) << "buffered_length=" << buffered_length |
- << "; max=" << max_decode_buffer_size_bytes_; |
- if (buffered_length > max_decode_buffer_size_bytes_) { |
- DVLOG(1) << "Header length (" << buffered_length |
- << ") is longer than permitted (" |
- << max_decode_buffer_size_bytes_ << ")"; |
- SetErrorDetected(); |
- } |
- } |
- return !error_detected_; |
-} |
- |
-void HpackDecoder2::HandleHeaderRepresentation(StringPiece name, |
- StringPiece value) { |
- DVLOG(2) << "HpackDecoder2::HandleHeaderRepresentation:\n name: " << name |
- << "\n value: " << value; |
- total_header_bytes_ += name.size() + value.size(); |
- header_seen_ = true; |
- if (handler_ == nullptr) { |
- DVLOG(3) << "HpackDecoder2::HandleHeaderRepresentation " |
- << "adding to decoded_block"; |
- decoded_block_.AppendValueOrAddHeader(name, value); |
- } else { |
- DVLOG(3) << "HpackDecoder2::HandleHeaderRepresentation " |
- << "passing to handler"; |
- DCHECK(decoded_block_.empty()); |
- handler_->OnHeader(name, value); |
- } |
-} |
- |
-} // namespace net |