// 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
