Index: net/spdy/spdy_headers_block_parser.cc |
diff --git a/net/spdy/spdy_headers_block_parser.cc b/net/spdy/spdy_headers_block_parser.cc |
deleted file mode 100644 |
index 154f6477356a444da5e397d2422e0abe30cff219..0000000000000000000000000000000000000000 |
--- a/net/spdy/spdy_headers_block_parser.cc |
+++ /dev/null |
@@ -1,196 +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/spdy_headers_block_parser.h" |
- |
-#include "base/sys_byteorder.h" |
- |
-namespace net { |
-namespace { |
- |
-// 0 is invalid according to both the SPDY 3.1 and HTTP/2 specifications. |
-const SpdyStreamId kInvalidStreamId = 0; |
- |
-} // anonymous namespace |
- |
-const size_t SpdyHeadersBlockParser::kMaximumFieldLength = 16 * 1024; |
- |
-SpdyHeadersBlockParser::SpdyHeadersBlockParser( |
- SpdyMajorVersion spdy_version, |
- SpdyHeadersHandlerInterface* handler) |
- : state_(READING_HEADER_BLOCK_LEN), |
- length_field_size_(LengthFieldSizeForVersion(spdy_version)), |
- max_headers_in_block_(MaxNumberOfHeadersForVersion(spdy_version)), |
- total_bytes_received_(0), |
- remaining_key_value_pairs_for_frame_(0), |
- handler_(handler), |
- stream_id_(kInvalidStreamId), |
- error_(NO_PARSER_ERROR), |
- spdy_version_(spdy_version) { |
- // The handler that we set must not be NULL. |
- DCHECK(handler_ != NULL); |
-} |
- |
-SpdyHeadersBlockParser::~SpdyHeadersBlockParser() {} |
- |
-bool SpdyHeadersBlockParser::HandleControlFrameHeadersData( |
- SpdyStreamId stream_id, |
- const char* headers_data, |
- size_t headers_data_length) { |
- if (error_ == NEED_MORE_DATA) { |
- error_ = NO_PARSER_ERROR; |
- } |
- if (error_ != NO_PARSER_ERROR) { |
- LOG(DFATAL) << "Unexpected error: " << error_; |
- return false; |
- } |
- |
- // If this is the first call with the current header block, |
- // save its stream id. |
- if (state_ == READING_HEADER_BLOCK_LEN && stream_id_ == kInvalidStreamId) { |
- stream_id_ = stream_id; |
- } |
- if (stream_id != stream_id_) { |
- LOG(DFATAL) << "Unexpected stream id: " << stream_id << " (expected " |
- << stream_id_ << ")"; |
- error_ = UNEXPECTED_STREAM_ID; |
- return false; |
- } |
- if (stream_id_ == kInvalidStreamId) { |
- LOG(DFATAL) << "Expected nonzero stream id, saw: " << stream_id_; |
- error_ = UNEXPECTED_STREAM_ID; |
- return false; |
- } |
- total_bytes_received_ += headers_data_length; |
- |
- SpdyPinnableBufferPiece prefix, key, value; |
- // Simultaneously tie lifetimes to the stack, and clear member variables. |
- prefix.Swap(&headers_block_prefix_); |
- key.Swap(&key_); |
- |
- // Apply the parsing state machine to the remaining prefix |
- // from last invocation, plus newly-available headers data. |
- Reader reader(prefix.buffer(), prefix.length(), |
- headers_data, headers_data_length); |
- while (error_ == NO_PARSER_ERROR) { |
- ParserState next_state(FINISHED_HEADER); |
- |
- switch (state_) { |
- case READING_HEADER_BLOCK_LEN: |
- next_state = READING_KEY_LEN; |
- ParseBlockLength(&reader); |
- break; |
- case READING_KEY_LEN: |
- next_state = READING_KEY; |
- ParseFieldLength(&reader); |
- break; |
- case READING_KEY: |
- next_state = READING_VALUE_LEN; |
- if (!reader.ReadN(next_field_length_, &key)) { |
- error_ = NEED_MORE_DATA; |
- } |
- break; |
- case READING_VALUE_LEN: |
- next_state = READING_VALUE; |
- ParseFieldLength(&reader); |
- break; |
- case READING_VALUE: |
- next_state = FINISHED_HEADER; |
- if (!reader.ReadN(next_field_length_, &value)) { |
- error_ = NEED_MORE_DATA; |
- } else { |
- handler_->OnHeader(key, value); |
- } |
- break; |
- case FINISHED_HEADER: |
- // Prepare for next header or block. |
- if (--remaining_key_value_pairs_for_frame_ > 0) { |
- next_state = READING_KEY_LEN; |
- } else { |
- next_state = READING_HEADER_BLOCK_LEN; |
- handler_->OnHeaderBlockEnd(total_bytes_received_); |
- stream_id_ = kInvalidStreamId; |
- // Expect to have consumed all buffer. |
- if (reader.Available() != 0) { |
- error_ = TOO_MUCH_DATA; |
- } |
- } |
- break; |
- } |
- |
- if (error_ == NO_PARSER_ERROR) { |
- state_ = next_state; |
- |
- if (next_state == READING_HEADER_BLOCK_LEN) { |
- // We completed reading a full header block. Return to caller. |
- total_bytes_received_ = 0; |
- break; |
- } |
- } else if (error_ == NEED_MORE_DATA) { |
- // We can't continue parsing until more data is available. Make copies of |
- // the key and buffer remainder, in preperation for the next invocation. |
- if (state_ > READING_KEY) { |
- key_.Swap(&key); |
- key_.Pin(); |
- } |
- reader.ReadN(reader.Available(), &headers_block_prefix_); |
- headers_block_prefix_.Pin(); |
- } |
- } |
- return error_ == NO_PARSER_ERROR; |
-} |
- |
-void SpdyHeadersBlockParser::ParseBlockLength(Reader* reader) { |
- ParseLength(reader, &remaining_key_value_pairs_for_frame_); |
- if (error_ == NO_PARSER_ERROR && |
- remaining_key_value_pairs_for_frame_ > max_headers_in_block_) { |
- error_ = HEADER_BLOCK_TOO_LARGE; |
- } |
- if (error_ == NO_PARSER_ERROR) { |
- handler_->OnHeaderBlock(remaining_key_value_pairs_for_frame_); |
- } |
-} |
- |
-void SpdyHeadersBlockParser::ParseFieldLength(Reader* reader) { |
- ParseLength(reader, &next_field_length_); |
- if (error_ == NO_PARSER_ERROR && next_field_length_ > kMaximumFieldLength) { |
- error_ = HEADER_FIELD_TOO_LARGE; |
- } |
-} |
- |
-void SpdyHeadersBlockParser::ParseLength(Reader* reader, |
- uint32_t* parsed_length) { |
- char buffer[] = {0, 0, 0, 0}; |
- if (!reader->ReadN(length_field_size_, buffer)) { |
- error_ = NEED_MORE_DATA; |
- return; |
- } |
- // Convert from network to host order and return the parsed out integer. |
- if (length_field_size_ == sizeof(uint32_t)) { |
- *parsed_length = ntohl(*reinterpret_cast<const uint32_t *>(buffer)); |
- } else { |
- *parsed_length = ntohs(*reinterpret_cast<const uint16_t *>(buffer)); |
- } |
-} |
- |
-size_t SpdyHeadersBlockParser::LengthFieldSizeForVersion( |
- SpdyMajorVersion spdy_version) { |
- if (spdy_version < SPDY3) { |
- return sizeof(uint16_t); |
- } |
- return sizeof(uint32_t); |
-} |
- |
-size_t SpdyHeadersBlockParser::MaxNumberOfHeadersForVersion( |
- SpdyMajorVersion spdy_version) { |
- // Account for the length of the header block field. |
- size_t max_bytes_for_headers = |
- kMaximumFieldLength - LengthFieldSizeForVersion(spdy_version); |
- |
- // A minimal size header is twice the length field size (and has a |
- // zero-lengthed key and a zero-lengthed value). |
- return max_bytes_for_headers / (2 * LengthFieldSizeForVersion(spdy_version)); |
-} |
- |
-} // namespace net |