// Copyright (c) 2012 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.

// TODO(rtenhove) clean up frame buffer size calculations so that we aren't
// constantly adding and subtracting header sizes; this is ugly and error-
// prone.

#include "net/spdy/spdy_framer.h"

#include "base/lazy_instance.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/stats_counters.h"
#include "base/third_party/valgrind/memcheck.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_frame_reader.h"
#include "net/spdy/spdy_bitmasks.h"

#if defined(USE_SYSTEM_ZLIB)
#include <zlib.h>
#else
#include "third_party/zlib/zlib.h"
#endif

using std::vector;

namespace net {

namespace {

// Compute the id of our dictionary so that we know we're using the
// right one when asked for it.
uLong CalculateDictionaryId(const char* dictionary,
                            const size_t dictionary_size) {
  uLong initial_value = adler32(0L, Z_NULL, 0);
  return adler32(initial_value,
                 reinterpret_cast<const Bytef*>(dictionary),
                 dictionary_size);
}

struct DictionaryIds {
  DictionaryIds()
    : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
      v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
  {}
  const uLong v2_dictionary_id;
  const uLong v3_dictionary_id;
};

// Adler ID for the SPDY header compressor dictionaries. Note that they are
// initialized lazily to avoid static initializers.
base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;

}  // namespace

const int SpdyFramer::kMinSpdyVersion = 2;
const int SpdyFramer::kMaxSpdyVersion = 3;
const SpdyStreamId SpdyFramer::kInvalidStream = -1;
const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
const size_t SpdyFramer::kControlFrameBufferSize =
    sizeof(SpdySynStreamControlFrameBlock);
const size_t SpdyFramer::kMaxControlFrameSize = 16 * 1024;

#ifdef DEBUG_SPDY_STATE_CHANGES
#define CHANGE_STATE(newstate)                                  \
  do {                                                          \
    LOG(INFO) << "Changing state from: "                        \
              << StateToString(state_)                          \
              << " to " << StateToString(newstate) << "\n";     \
    DCHECK(state_ != SPDY_ERROR);                               \
    DCHECK_EQ(previous_state_, state_);                         \
    previous_state_ = state_;                                   \
    state_ = newstate;                                          \
  } while (false)
#else
#define CHANGE_STATE(newstate)                                  \
  do {                                                          \
    DCHECK(state_ != SPDY_ERROR);                               \
    DCHECK_EQ(previous_state_, state_);                         \
    previous_state_ = state_;                                   \
    state_ = newstate;                                          \
  } while (false)
#endif

SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version,
                                                      uint32 wire) {
  if (version < 3) {
    ConvertFlagsAndIdForSpdy2(&wire);
  }
  return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
}

SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
    : flags_(flags), id_(id & 0x00ffffff) {
  DCHECK_GT(1u << 24, id) << "SPDY setting ID too large.";
}

uint32 SettingsFlagsAndId::GetWireFormat(int version) const {
  uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
  if (version < 3) {
    ConvertFlagsAndIdForSpdy2(&wire);
  }
  return wire;
}

// SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
// This method is used to preserve buggy behavior and works on both
// little-endian and big-endian hosts.
// This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
// as well as vice versa).
void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
    uint8* wire_array = reinterpret_cast<uint8*>(val);
    std::swap(wire_array[0], wire_array[3]);
    std::swap(wire_array[1], wire_array[2]);
}

SpdyCredential::SpdyCredential() : slot(0) {}
SpdyCredential::~SpdyCredential() {}

SpdyFramer::SpdyFramer(int version)
    : state_(SPDY_RESET),
      previous_state_(SPDY_RESET),
      error_code_(SPDY_NO_ERROR),
      remaining_data_(0),
      remaining_control_payload_(0),
      remaining_control_header_(0),
      current_frame_buffer_(new char[kControlFrameBufferSize]),
      current_frame_len_(0),
      enable_compression_(true),
      visitor_(NULL),
      display_protocol_("SPDY"),
      spdy_version_(version),
      syn_frame_processed_(false),
      probable_http_response_(false) {
  DCHECK_GE(kMaxSpdyVersion, version);
  DCHECK_LE(kMinSpdyVersion, version);
}

SpdyFramer::~SpdyFramer() {
  if (header_compressor_.get()) {
    deflateEnd(header_compressor_.get());
  }
  if (header_decompressor_.get()) {
    inflateEnd(header_decompressor_.get());
  }
}

void SpdyFramer::Reset() {
  state_ = SPDY_RESET;
  previous_state_ = SPDY_RESET;
  error_code_ = SPDY_NO_ERROR;
  remaining_data_ = 0;
  remaining_control_payload_ = 0;
  remaining_control_header_ = 0;
  current_frame_len_ = 0;
  settings_scratch_.Reset();
}

const char* SpdyFramer::StateToString(int state) {
  switch (state) {
    case SPDY_ERROR:
      return "ERROR";
    case SPDY_DONE:
      return "DONE";
    case SPDY_AUTO_RESET:
      return "AUTO_RESET";
    case SPDY_RESET:
      return "RESET";
    case SPDY_READING_COMMON_HEADER:
      return "READING_COMMON_HEADER";
    case SPDY_CONTROL_FRAME_PAYLOAD:
      return "CONTROL_FRAME_PAYLOAD";
    case SPDY_IGNORE_REMAINING_PAYLOAD:
      return "IGNORE_REMAINING_PAYLOAD";
    case SPDY_FORWARD_STREAM_FRAME:
      return "FORWARD_STREAM_FRAME";
    case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
      return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
    case SPDY_CONTROL_FRAME_HEADER_BLOCK:
      return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
    case SPDY_CREDENTIAL_FRAME_PAYLOAD:
      return "SPDY_CREDENTIAL_FRAME_PAYLOAD";
    case SPDY_SETTINGS_FRAME_PAYLOAD:
      return "SPDY_SETTINGS_FRAME_PAYLOAD";
  }
  return "UNKNOWN_STATE";
}

void SpdyFramer::set_error(SpdyError error) {
  DCHECK(visitor_);
  error_code_ = error;
  CHANGE_STATE(SPDY_ERROR);
  visitor_->OnError(this);
}

const char* SpdyFramer::ErrorCodeToString(int error_code) {
  switch (error_code) {
    case SPDY_NO_ERROR:
      return "NO_ERROR";
    case SPDY_INVALID_CONTROL_FRAME:
      return "INVALID_CONTROL_FRAME";
    case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
      return "CONTROL_PAYLOAD_TOO_LARGE";
    case SPDY_ZLIB_INIT_FAILURE:
      return "ZLIB_INIT_FAILURE";
    case SPDY_UNSUPPORTED_VERSION:
      return "UNSUPPORTED_VERSION";
    case SPDY_DECOMPRESS_FAILURE:
      return "DECOMPRESS_FAILURE";
    case SPDY_COMPRESS_FAILURE:
      return "COMPRESS_FAILURE";
    case SPDY_INVALID_DATA_FRAME_FLAGS:
      return "SPDY_INVALID_DATA_FRAME_FLAGS";
  }
  return "UNKNOWN_ERROR";
}

const char* SpdyFramer::StatusCodeToString(int status_code) {
  switch (status_code) {
    case INVALID:
      return "INVALID";
    case PROTOCOL_ERROR:
      return "PROTOCOL_ERROR";
    case INVALID_STREAM:
      return "INVALID_STREAM";
    case REFUSED_STREAM:
      return "REFUSED_STREAM";
    case UNSUPPORTED_VERSION:
      return "UNSUPPORTED_VERSION";
    case CANCEL:
      return "CANCEL";
    case INTERNAL_ERROR:
      return "INTERNAL_ERROR";
    case FLOW_CONTROL_ERROR:
      return "FLOW_CONTROL_ERROR";
    case STREAM_IN_USE:
      return "STREAM_IN_USE";
    case STREAM_ALREADY_CLOSED:
      return "STREAM_ALREADY_CLOSED";
    case INVALID_CREDENTIALS:
      return "INVALID_CREDENTIALS";
    case FRAME_TOO_LARGE:
      return "FRAME_TOO_LARGE";
  }
  return "UNKNOWN_STATUS";
}

const char* SpdyFramer::ControlTypeToString(SpdyControlType type) {
  switch (type) {
    case SYN_STREAM:
      return "SYN_STREAM";
    case SYN_REPLY:
      return "SYN_REPLY";
    case RST_STREAM:
      return "RST_STREAM";
    case SETTINGS:
      return "SETTINGS";
    case NOOP:
      return "NOOP";
    case PING:
      return "PING";
    case GOAWAY:
      return "GOAWAY";
    case HEADERS:
      return "HEADERS";
    case WINDOW_UPDATE:
      return "WINDOW_UPDATE";
    case CREDENTIAL:
      return "CREDENTIAL";
    case NUM_CONTROL_FRAME_TYPES:
      break;
  }
  return "UNKNOWN_CONTROL_TYPE";
}

size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
  DCHECK(visitor_);
  DCHECK(data);

  size_t original_len = len;
  do {
    previous_state_ = state_;
    switch (state_) {
      case SPDY_ERROR:
      case SPDY_DONE:
        goto bottom;

      case SPDY_AUTO_RESET:
      case SPDY_RESET:
        Reset();
        if (len > 0) {
          CHANGE_STATE(SPDY_READING_COMMON_HEADER);
        }
        break;

      case SPDY_READING_COMMON_HEADER: {
        size_t bytes_read = ProcessCommonHeader(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
        // Control frames that contain header blocks (SYN_STREAM, SYN_REPLY,
        // HEADERS) take a different path through the state machine - they
        // will go:
        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
        //   2. SPDY_CONTROL_FRAME_HEADER_BLOCK
        //
        // SETTINGS frames take a slightly modified route:
        //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
        //   2. SPDY_SETTINGS_FRAME_PAYLOAD
        //
        //  All other control frames will use the alternate route directly to
        //  SPDY_CONTROL_FRAME_PAYLOAD
        int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_SETTINGS_FRAME_PAYLOAD: {
        int bytes_read = ProcessSettingsFramePayload(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
        int bytes_read = ProcessControlFrameHeaderBlock(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_CREDENTIAL_FRAME_PAYLOAD: {
        size_t bytes_read = ProcessCredentialFramePayload(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_CONTROL_FRAME_PAYLOAD: {
        size_t bytes_read = ProcessControlFramePayload(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      case SPDY_IGNORE_REMAINING_PAYLOAD:
        // control frame has too-large payload
        // intentional fallthrough
      case SPDY_FORWARD_STREAM_FRAME: {
        size_t bytes_read = ProcessDataFramePayload(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }
      default:
        LOG(DFATAL) << "Invalid value for " << display_protocol_
                    << " framer state: " << state_;
        // This ensures that we don't infinite-loop if state_ gets an
        // invalid value somehow, such as due to a SpdyFramer getting deleted
        // from a callback it calls.
        goto bottom;
    }
  } while (state_ != previous_state_);
 bottom:
  DCHECK(len == 0 || state_ == SPDY_ERROR);
  if (current_frame_len_ == 0 &&
      remaining_data_ == 0 &&
      remaining_control_payload_ == 0 &&
      remaining_control_header_ == 0) {
    DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
        << "State: " << StateToString(state_);
  }

  return original_len - len;
}

size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
  // This should only be called when we're in the SPDY_READING_COMMON_HEADER
  // state.
  DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);

  size_t original_len = len;
  SpdyFrame current_frame(current_frame_buffer_.get(), false);

  // Update current frame buffer as needed.
  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
    size_t bytes_desired = SpdyFrame::kHeaderSize - current_frame_len_;
    UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
  }

  if (current_frame_len_ < SpdyFrame::kHeaderSize) {
    // TODO(rch): remove this empty block
    // Do nothing.
  } else {
    remaining_data_ = current_frame.length();

    // This is just a sanity check for help debugging early frame errors.
    if (remaining_data_ > 1000000u) {
      // The strncmp for 5 is safe because we only hit this point if we
      // have SpdyFrame::kHeaderSize (8) bytes
      if (!syn_frame_processed_ &&
          strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
        LOG(WARNING) << "Unexpected HTTP response to spdy request";
        probable_http_response_ = true;
      } else {
        LOG(WARNING) << "Unexpectedly large frame.  " << display_protocol_
                     << " session is likely corrupt.";
      }
    }

    // if we're here, then we have the common header all received.
    if (!current_frame.is_control_frame()) {
      SpdyDataFrame data_frame(current_frame_buffer_.get(), false);
      visitor_->OnDataFrameHeader(&data_frame);

      if (current_frame.length() > 0) {
        CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
      } else {
        // Empty data frame.
        if (current_frame.flags() & DATA_FLAG_FIN) {
          visitor_->OnStreamFrameData(data_frame.stream_id(),
                                      NULL, 0, DATA_FLAG_FIN);
        }
        CHANGE_STATE(SPDY_AUTO_RESET);
      }
    } else {
      ProcessControlFrameHeader();
    }
  }
  return original_len - len;
}

void SpdyFramer::ProcessControlFrameHeader() {
  DCHECK_EQ(SPDY_NO_ERROR, error_code_);
  DCHECK_LE(static_cast<size_t>(SpdyFrame::kHeaderSize), current_frame_len_);
  SpdyControlFrame current_control_frame(current_frame_buffer_.get(), false);

  // We check version before we check validity: version can never be 'invalid',
  // it can only be unsupported.
  if (current_control_frame.version() != spdy_version_) {
    DLOG(INFO) << "Unsupported SPDY version " << current_control_frame.version()
               << " (expected " << spdy_version_ << ")";
    set_error(SPDY_UNSUPPORTED_VERSION);
    return;
  }

  // Next up, check to see if we have valid data.  This should be after version
  // checking (otherwise if the the type were out of bounds due to a version
  // upgrade we would misclassify the error) and before checking the type
  // (type can definitely be out of bounds)
  if (!current_control_frame.AppearsToBeAValidControlFrame()) {
    set_error(SPDY_INVALID_CONTROL_FRAME);
    return;
  }

  if (current_control_frame.type() == NOOP) {
    DLOG(INFO) << "NOOP control frame found. Ignoring.";
    CHANGE_STATE(SPDY_AUTO_RESET);
    return;
  }

  // Do some sanity checking on the control frame sizes.
  switch (current_control_frame.type()) {
    case SYN_STREAM:
      if (current_control_frame.length() <
          SpdySynStreamControlFrame::size() - SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case SYN_REPLY:
      if (current_control_frame.length() <
          SpdySynReplyControlFrame::size() - SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case RST_STREAM:
      if (current_control_frame.length() !=
          SpdyRstStreamControlFrame::size() - SpdyFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case SETTINGS:
      // Make sure that we have an integral number of 8-byte key/value pairs,
      // plus a 4-byte length field.
      if (current_control_frame.length() <
          SpdySettingsControlFrame::size() - SpdyControlFrame::kHeaderSize ||
          (current_control_frame.length() % 8 != 4)) {
        DLOG(WARNING) << "Invalid length for SETTINGS frame: "
                      << current_control_frame.length();
        set_error(SPDY_INVALID_CONTROL_FRAME);
      }
      break;
    case GOAWAY:
      {
        // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account
        // for this difference via a separate offset variable, since
        // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
        const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
        if (current_control_frame.length() + goaway_offset !=
            SpdyGoAwayControlFrame::size() - SpdyFrame::kHeaderSize)
          set_error(SPDY_INVALID_CONTROL_FRAME);
        break;
      }
    case HEADERS:
      if (current_control_frame.length() <
          SpdyHeadersControlFrame::size() - SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case WINDOW_UPDATE:
      if (current_control_frame.length() !=
          SpdyWindowUpdateControlFrame::size() -
          SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case PING:
      if (current_control_frame.length() !=
          SpdyPingControlFrame::size() - SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    case CREDENTIAL:
      if (current_control_frame.length() <
          SpdyCredentialControlFrame::size() - SpdyControlFrame::kHeaderSize)
        set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
    default:
      LOG(WARNING) << "Valid " << display_protocol_
                   << " control frame with unhandled type: "
                   << current_control_frame.type();
      DLOG(FATAL);
      set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
  }

  if (state_ == SPDY_ERROR) {
    return;
  }

  remaining_control_payload_ = current_control_frame.length();
  const size_t total_frame_size =
      remaining_control_payload_ + SpdyFrame::kHeaderSize;
  if (total_frame_size > kMaxControlFrameSize) {
    DLOG(WARNING) << "Received control frame with way too big of a payload: "
                  << total_frame_size;
    set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    return;
  }

  if (current_control_frame.type() == CREDENTIAL) {
    CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD);
    return;
  }

  // Determine the frame size without variable-length data.
  int32 frame_size_without_variable_data;
  switch (current_control_frame.type()) {
    case SYN_STREAM:
      syn_frame_processed_ = true;
      frame_size_without_variable_data = SpdySynStreamControlFrame::size();
      break;
    case SYN_REPLY:
      syn_frame_processed_ = true;
      frame_size_without_variable_data = SpdySynReplyControlFrame::size();
      // SPDY 2 had two bytes of unused space preceeding payload.
      if (spdy_version_ < 3) {
        frame_size_without_variable_data += 2;
      }
      break;
    case HEADERS:
      frame_size_without_variable_data = SpdyHeadersControlFrame::size();
      // SPDY 2 had two bytes of unused space preceeding payload.
      if (spdy_version_ < 3) {
        frame_size_without_variable_data += 2;
      }
      break;
    case SETTINGS:
      frame_size_without_variable_data = SpdySettingsControlFrame::size();
      break;
    default:
      frame_size_without_variable_data = -1;
      break;
  }

  if ((frame_size_without_variable_data == -1) &&
      (total_frame_size > kControlFrameBufferSize)) {
    // We should already be in an error state. Double-check.
    DCHECK_EQ(SPDY_ERROR, state_);
    if (state_ != SPDY_ERROR) {
      LOG(DFATAL) << display_protocol_
                  << " control frame buffer too small for fixed-length frame.";
      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    }
    return;
  }
  if (frame_size_without_variable_data > 0) {
    // We have a control frame with a header block. We need to parse the
    // remainder of the control frame's header before we can parse the header
    // block. The start of the header block varies with the control type.
    DCHECK_GE(frame_size_without_variable_data,
              static_cast<int32>(current_frame_len_));
    remaining_control_header_ = frame_size_without_variable_data -
        current_frame_len_;
    remaining_control_payload_ += SpdyFrame::kHeaderSize -
        frame_size_without_variable_data;
    CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
    return;
  }

  CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
}

size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
                                            size_t max_bytes) {
  size_t bytes_to_read = std::min(*len, max_bytes);
  DCHECK_GE(kControlFrameBufferSize, current_frame_len_ + bytes_to_read);
  memcpy(current_frame_buffer_.get() + current_frame_len_,
         *data,
         bytes_to_read);
  current_frame_len_ += bytes_to_read;
  *data += bytes_to_read;
  *len -= bytes_to_read;
  return bytes_to_read;
}

size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock* headers) const {
  const size_t num_name_value_pairs_size
      = (spdy_version_ < 3) ? sizeof(uint16) : sizeof(uint32);
  const size_t length_of_name_size = num_name_value_pairs_size;
  const size_t length_of_value_size = num_name_value_pairs_size;

  size_t total_length = num_name_value_pairs_size;
  for (SpdyHeaderBlock::const_iterator it = headers->begin();
       it != headers->end();
       ++it) {
    // We add space for the length of the name and the length of the value as
    // well as the length of the name and the length of the value.
    total_length += length_of_name_size + it->first.size() +
                    length_of_value_size + it->second.size();
  }
  return total_length;
}

void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
                                  const SpdyHeaderBlock* headers) const {
  if (spdy_version_ < 3) {
    frame->WriteUInt16(headers->size());  // Number of headers.
  } else {
    frame->WriteUInt32(headers->size());  // Number of headers.
  }
  SpdyHeaderBlock::const_iterator it;
  for (it = headers->begin(); it != headers->end(); ++it) {
    bool wrote_header;
    if (spdy_version_ < 3) {
      wrote_header = frame->WriteString(it->first);
      wrote_header &= frame->WriteString(it->second);
    } else {
      wrote_header = frame->WriteStringPiece32(it->first);
      wrote_header &= frame->WriteStringPiece32(it->second);
    }
    DCHECK(wrote_header);
  }
}

// TODO(phajdan.jr): Clean up after we no longer need
// to workaround http://crbug.com/139744.
#if !defined(USE_SYSTEM_ZLIB)

// These constants are used by zlib to differentiate between normal data and
// cookie data. Cookie data is handled specially by zlib when compressing.
enum ZDataClass {
  // kZStandardData is compressed normally, save that it will never match
  // against any other class of data in the window.
  kZStandardData = Z_CLASS_STANDARD,
  // kZCookieData is compressed in its own Huffman blocks and only matches in
  // its entirety and only against other kZCookieData blocks. Any matches must
  // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
  // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
  // prefix matches.
  kZCookieData = Z_CLASS_COOKIE,
  // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
  // against the window.
  kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
};

// WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
// needed when switching between classes of data.
static void WriteZ(const base::StringPiece& data,
                   ZDataClass clas,
                   z_stream* out) {
  int rv;

  // If we are switching from standard to non-standard data then we need to end
  // the current Huffman context to avoid it leaking between them.
  if (out->clas == kZStandardData &&
      clas != kZStandardData) {
    out->avail_in = 0;
    rv = deflate(out, Z_PARTIAL_FLUSH);
    DCHECK_EQ(Z_OK, rv);
    DCHECK_EQ(0u, out->avail_in);
    DCHECK_LT(0u, out->avail_out);
  }

  out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
  out->avail_in = data.size();
  out->clas = clas;
  if (clas == kZStandardData) {
    rv = deflate(out, Z_NO_FLUSH);
  } else {
    rv = deflate(out, Z_PARTIAL_FLUSH);
  }
  DCHECK_EQ(Z_OK, rv);
  DCHECK_EQ(0u, out->avail_in);
  DCHECK_LT(0u, out->avail_out);
}

// WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
static void WriteLengthZ(size_t n,
                         unsigned length,
                         ZDataClass clas,
                         z_stream* out) {
  char buf[4];
  DCHECK_LE(length, sizeof(buf));
  for (unsigned i = 1; i <= length; i++) {
    buf[length - i] = n;
    n >>= 8;
  }
  WriteZ(base::StringPiece(buf, length), clas, out);
}

// WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
// manner that resists the length of the compressed data from compromising
// cookie data.
void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
                                     z_stream* z) const {
  unsigned length_length = 4;
  if (spdy_version_ < 3)
    length_length = 2;

  WriteLengthZ(headers->size(), length_length, kZStandardData, z);

  std::map<std::string, std::string>::const_iterator it;
  for (it = headers->begin(); it != headers->end(); ++it) {
    WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
    WriteZ(it->first, kZStandardData, z);

    if (it->first == "cookie") {
      // We require the cookie values (save for the last) to end with a
      // semicolon and (save for the first) to start with a space. This is
      // typically the format that we are given them in but we reserialize them
      // to be sure.

      std::vector<base::StringPiece> cookie_values;
      size_t cookie_length = 0;
      base::StringPiece cookie_data(it->second);

      for (;;) {
        while (!cookie_data.empty() &&
               (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
          cookie_data.remove_prefix(1);
        }
        if (cookie_data.empty())
          break;

        size_t i;
        for (i = 0; i < cookie_data.size(); i++) {
          if (cookie_data[i] == ';')
            break;
        }
        if (i < cookie_data.size()) {
          cookie_values.push_back(cookie_data.substr(0, i));
          cookie_length += i + 2 /* semicolon and space */;
          cookie_data.remove_prefix(i + 1);
        } else {
          cookie_values.push_back(cookie_data);
          cookie_length += cookie_data.size();
          cookie_data.remove_prefix(i);
        }
      }

      WriteLengthZ(cookie_length, length_length, kZStandardData, z);
      for (size_t i = 0; i < cookie_values.size(); i++) {
        std::string cookie;
        // Since zlib will only back-reference complete cookies, a cookie that
        // is currently last (and so doesn't have a trailing semicolon) won't
        // match if it's later in a non-final position. The same is true of
        // the first cookie.
        if (i == 0 && cookie_values.size() == 1) {
          cookie = cookie_values[i].as_string();
        } else if (i == 0) {
          cookie = cookie_values[i].as_string() + ";";
        } else if (i < cookie_values.size() - 1) {
          cookie = " " + cookie_values[i].as_string() + ";";
        } else {
          cookie = " " + cookie_values[i].as_string();
        }
        WriteZ(cookie, kZCookieData, z);
      }
    } else if (it->first == "accept" ||
               it->first == "accept-charset" ||
               it->first == "accept-encoding" ||
               it->first == "accept-language" ||
               it->first == "host" ||
               it->first == "version" ||
               it->first == "method" ||
               it->first == "scheme" ||
               it->first == ":host" ||
               it->first == ":version" ||
               it->first == ":method" ||
               it->first == ":scheme" ||
               it->first == "user-agent") {
      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
      WriteZ(it->second, kZStandardData, z);
    } else {
      // Non-whitelisted headers are Huffman compressed in their own block, but
      // don't match against the window.
      WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
      WriteZ(it->second, kZHuffmanOnlyData, z);
    }
  }

  z->avail_in = 0;
  int rv = deflate(z, Z_SYNC_FLUSH);
  DCHECK_EQ(Z_OK, rv);
  z->clas = kZStandardData;
}
#endif  // !defined(USE_SYSTEM_ZLIB)

size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
                                                        size_t len) {
  DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
  size_t original_len = len;

  if (remaining_control_header_ > 0) {
    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
                                                 remaining_control_header_);
    remaining_control_header_ -= bytes_read;
  }

  if (remaining_control_header_ == 0) {
    SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
    switch (control_frame.type()) {
      case SYN_STREAM:
        {
          SpdySynStreamControlFrame* syn_stream_frame =
              reinterpret_cast<SpdySynStreamControlFrame*>(&control_frame);
          // TODO(hkhalil): Check that invalid flag bits are unset?
          visitor_->OnSynStream(
              syn_stream_frame->stream_id(),
              syn_stream_frame->associated_stream_id(),
              syn_stream_frame->priority(),
              syn_stream_frame->credential_slot(),
              (syn_stream_frame->flags() & CONTROL_FLAG_FIN) != 0,
              (syn_stream_frame->flags() & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
        }
        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
        break;
      case SYN_REPLY:
        {
          SpdySynReplyControlFrame* syn_reply_frame =
              reinterpret_cast<SpdySynReplyControlFrame*>(&control_frame);
          visitor_->OnSynReply(
              syn_reply_frame->stream_id(),
              (syn_reply_frame->flags() & CONTROL_FLAG_FIN) != 0);
        }
        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
        break;
      case HEADERS:
        {
          SpdyHeadersControlFrame* headers_frame =
              reinterpret_cast<SpdyHeadersControlFrame*>(&control_frame);
          visitor_->OnHeaders(
              headers_frame->stream_id(),
              (headers_frame->flags() & CONTROL_FLAG_FIN) != 0);
        }
        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
        break;
      case SETTINGS:
        CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
        break;
      default:
        DCHECK(false);
    }
  }
  return original_len - len;
}

// Does not buffer the control payload. Instead, either passes directly to the
// visitor or decompresses and then passes directly to the visitor, via
// IncrementallyDeliverControlFrameHeaderData() or
// IncrementallyDecompressControlFrameHeaderData() respectively.
size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
                                                  size_t data_len) {
  DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);

  bool processed_successfully = true;
  DCHECK(control_frame.type() == SYN_STREAM ||
         control_frame.type() == SYN_REPLY ||
         control_frame.type() == HEADERS);
  size_t process_bytes = std::min(data_len, remaining_control_payload_);
  if (process_bytes > 0) {
    if (enable_compression_) {
      processed_successfully = IncrementallyDecompressControlFrameHeaderData(
          &control_frame, data, process_bytes);
    } else {
      processed_successfully = IncrementallyDeliverControlFrameHeaderData(
          &control_frame, data, process_bytes);
    }

    remaining_control_payload_ -= process_bytes;
    remaining_data_ -= process_bytes;
  }

  // Handle the case that there is no futher data in this frame.
  if (remaining_control_payload_ == 0 && processed_successfully) {
    // The complete header block has been delivered. We send a zero-length
    // OnControlFrameHeaderData() to indicate this.
    visitor_->OnControlFrameHeaderData(
        GetControlFrameStreamId(&control_frame), NULL, 0);

    // If this is a FIN, tell the caller.
    if (control_frame.flags() & CONTROL_FLAG_FIN) {
      visitor_->OnStreamFrameData(GetControlFrameStreamId(&control_frame),
                                  NULL, 0, DATA_FLAG_FIN);
    }

    CHANGE_STATE(SPDY_AUTO_RESET);
  }

  // Handle error.
  if (!processed_successfully) {
    return data_len;
  }

  // Return amount processed.
  return process_bytes;
}

size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
                                               size_t data_len) {
  DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
  SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
  DCHECK_EQ(SETTINGS, control_frame.type());
  size_t unprocessed_bytes = std::min(data_len, remaining_control_payload_);
  size_t processed_bytes = 0;

  // Loop over our incoming data.
  while (unprocessed_bytes > 0) {
    // Process up to one setting at a time.
    size_t processing = std::min(
        unprocessed_bytes,
        static_cast<size_t>(8 - settings_scratch_.setting_buf_len));

    // Check if we have a complete setting in our input.
    if (processing == 8) {
      // Parse the setting directly out of the input without buffering.
      if (!ProcessSetting(data + processed_bytes)) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
        return processed_bytes;
      }
    } else {
      // Continue updating settings_scratch_.setting_buf.
      memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
             data + processed_bytes,
             processing);
      settings_scratch_.setting_buf_len += processing;

      // Check if we have a complete setting buffered.
      if (settings_scratch_.setting_buf_len == 8) {
        if (!ProcessSetting(settings_scratch_.setting_buf)) {
          set_error(SPDY_INVALID_CONTROL_FRAME);
          return processed_bytes;
        }
        // Reset settings_scratch_.setting_buf for our next setting.
        settings_scratch_.setting_buf_len = 0;
      }
    }

    // Iterate.
    unprocessed_bytes -= processing;
    processed_bytes += processing;
  }

  // Check if we're done handling this SETTINGS frame.
  remaining_control_payload_ -= processed_bytes;
  if (remaining_control_payload_ == 0) {
    CHANGE_STATE(SPDY_AUTO_RESET);
  }

  return processed_bytes;
}

bool SpdyFramer::ProcessSetting(const char* data) {
  // Extract fields.
  // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
  const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
  SettingsFlagsAndId id_and_flags =
      SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire);
  uint8 flags = id_and_flags.flags();
  uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));

  // Validate id.
  switch (id_and_flags.id()) {
    case SETTINGS_UPLOAD_BANDWIDTH:
    case SETTINGS_DOWNLOAD_BANDWIDTH:
    case SETTINGS_ROUND_TRIP_TIME:
    case SETTINGS_MAX_CONCURRENT_STREAMS:
    case SETTINGS_CURRENT_CWND:
    case SETTINGS_DOWNLOAD_RETRANS_RATE:
    case SETTINGS_INITIAL_WINDOW_SIZE:
      // Valid values.
      break;
    default:
      DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id();
      return false;
  }
  SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id());

  // Detect duplciates.
  if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
    DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
                  << " in " << display_protocol_ << " SETTINGS frame "
                  << "(last settikng id was "
                  << settings_scratch_.last_setting_id << ").";
    return false;
  }
  settings_scratch_.last_setting_id = id;

  // Validate flags.
  uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
  if ((flags & ~(kFlagsMask)) != 0) {
    DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
                  << flags;
    return false;
  }

  // Validation succeeded. Pass on to visitor.
  visitor_->OnSetting(id, flags, value);
  return true;
}

size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
  size_t original_len = len;
  if (remaining_control_payload_) {
    size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
                                                 remaining_control_payload_);
    remaining_control_payload_ -= bytes_read;
    remaining_data_ -= bytes_read;
    if (remaining_control_payload_ == 0) {
      SpdyControlFrame control_frame(current_frame_buffer_.get(), false);
      DCHECK(!control_frame.has_header_block());
      // Use frame-specific handlers.
      switch (control_frame.type()) {
        case PING: {
            SpdyPingControlFrame* ping_frame =
                reinterpret_cast<SpdyPingControlFrame*>(&control_frame);
            visitor_->OnPing(ping_frame->unique_id());
          }
          break;
        case WINDOW_UPDATE: {
            SpdyWindowUpdateControlFrame *window_update_frame =
                reinterpret_cast<SpdyWindowUpdateControlFrame*>(&control_frame);
            visitor_->OnWindowUpdate(window_update_frame->stream_id(),
                                     window_update_frame->delta_window_size());
          }
          break;
        case RST_STREAM: {
            SpdyRstStreamControlFrame* rst_stream_frame =
                reinterpret_cast<SpdyRstStreamControlFrame*>(&control_frame);
            visitor_->OnRstStream(rst_stream_frame->stream_id(),
                                  rst_stream_frame->status());
          }
          break;
        case GOAWAY: {
            SpdyGoAwayControlFrame* go_away_frame =
                reinterpret_cast<SpdyGoAwayControlFrame*>(&control_frame);
            if (spdy_version_ < 3) {
              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
                                 GOAWAY_OK);
            } else {
              visitor_->OnGoAway(go_away_frame->last_accepted_stream_id(),
                                 go_away_frame->status());
            }
          }
          break;
        default:
          // Unreachable.
          LOG(FATAL) << "Unhandled control frame " << control_frame.type();
      }

      CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
    }
  }
  return original_len - len;
}

size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) {
  if (len > 0) {
    // Process only up to the end of this CREDENTIAL frame.
    len = std::min(len, remaining_control_payload_);
    bool processed_succesfully = visitor_->OnCredentialFrameData(data, len);
    remaining_control_payload_ -= len;
    remaining_data_ -= len;
    if (!processed_succesfully) {
      set_error(SPDY_CREDENTIAL_FRAME_CORRUPT);
    } else if (remaining_control_payload_ == 0) {
      visitor_->OnCredentialFrameData(NULL, 0);
      CHANGE_STATE(SPDY_AUTO_RESET);
    }
  }
  return len;
}

size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
  size_t original_len = len;

  SpdyDataFrame current_data_frame(current_frame_buffer_.get(), false);
  if (remaining_data_ > 0) {
    size_t amount_to_forward = std::min(remaining_data_, len);
    if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
      // Only inform the visitor if there is data.
      if (amount_to_forward) {
        visitor_->OnStreamFrameData(current_data_frame.stream_id(),
                                    data, amount_to_forward, SpdyDataFlags());
      }
    }
    data += amount_to_forward;
    len -= amount_to_forward;
    remaining_data_ -= amount_to_forward;

    // If the FIN flag is set, and there is no more data in this data
    // frame, inform the visitor of EOF via a 0-length data frame.
    if (!remaining_data_ &&
        current_data_frame.flags() & DATA_FLAG_FIN) {
      visitor_->OnStreamFrameData(current_data_frame.stream_id(),
                                  NULL, 0, DATA_FLAG_FIN);
    }
  }

  if (remaining_data_ == 0) {
    CHANGE_STATE(SPDY_AUTO_RESET);
  }
  return original_len - len;
}

bool SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
                                          size_t header_length,
                                          SpdyHeaderBlock* block) const {
  SpdyFrameReader reader(header_data, header_length);

  // Read number of headers.
  uint32 num_headers;
  if (spdy_version_ < 3) {
    uint16 temp;
    if (!reader.ReadUInt16(&temp)) {
      DLOG(INFO) << "Unable to read number of headers.";
      return false;
    }
    num_headers = temp;
  } else {
    if (!reader.ReadUInt32(&num_headers)) {
      DLOG(INFO) << "Unable to read number of headers.";
      return false;
    }
  }

  // Read each header.
  for (uint32 index = 0; index < num_headers; ++index) {
    base::StringPiece temp;

    // Read header name.
    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
                            : !reader.ReadStringPiece32(&temp)) {
      DLOG(INFO) << "Unable to read header name (" << index + 1 << " of "
                 << num_headers << ").";
      return false;
    }
    std::string name = temp.as_string();

    // Read header value.
    if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
                            : !reader.ReadStringPiece32(&temp)) {
      DLOG(INFO) << "Unable to read header value (" << index + 1 << " of "
                 << num_headers << ").";
      return false;
    }
    std::string value = temp.as_string();

    // Ensure no duplicates.
    if (block->find(name) != block->end()) {
      DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of "
                 << num_headers << ").";
      return false;
    }

    // Store header.
    (*block)[name] = value;
  }
  return true;
}

// TODO(hkhalil): Remove, or move to test utils kit.
/* static */
bool SpdyFramer::ParseSettings(const SpdySettingsControlFrame* frame,
                               SettingsMap* settings) {
  DCHECK_EQ(frame->type(), SETTINGS);
  DCHECK(settings);

  SpdyFrameReader parser(frame->header_block(), frame->header_block_len());
  for (size_t index = 0; index < frame->num_entries(); ++index) {
    uint32 id_and_flags_wire;
    uint32 value;
    // SettingsFlagsAndId accepts off-the-wire (network byte order) data, so we
    // use ReadBytes() instead of ReadUInt32() as the latter calls ntohl().
    if (!parser.ReadBytes(&id_and_flags_wire, 4)) {
      return false;
    }
    if (!parser.ReadUInt32(&value))
      return false;
    SettingsFlagsAndId flags_and_id =
        SettingsFlagsAndId::FromWireFormat(frame->version(), id_and_flags_wire);
    SpdySettingsIds id = static_cast<SpdySettingsIds>(flags_and_id.id());
    SpdySettingsFlags flags =
        static_cast<SpdySettingsFlags>(flags_and_id.flags());
    (*settings)[id] = SettingsFlagsAndValue(flags, value);
  }
  return true;
}

/* static */
bool SpdyFramer::ParseCredentialData(const char* data, size_t len,
                                     SpdyCredential* credential) {
  DCHECK(credential);

  SpdyFrameReader parser(data, len);
  base::StringPiece temp;
  if (!parser.ReadUInt16(&credential->slot)) {
    return false;
  }

  if (!parser.ReadStringPiece32(&temp)) {
    return false;
  }
  credential->proof = temp.as_string();

  while (!parser.IsDoneReading()) {
    if (!parser.ReadStringPiece32(&temp)) {
      return false;
    }
    credential->certs.push_back(temp.as_string());
  }
  return true;
}

SpdySynStreamControlFrame* SpdyFramer::CreateSynStream(
    SpdyStreamId stream_id,
    SpdyStreamId associated_stream_id,
    SpdyPriority priority,
    uint8 credential_slot,
    SpdyControlFlags flags,
    bool compressed,
    const SpdyHeaderBlock* headers) {
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
  DCHECK_EQ(0u, associated_stream_id & ~kStreamIdMask);

  // Find our length.
  size_t frame_size = SpdySynStreamControlFrame::size() +
                      GetSerializedLength(headers);

  SpdyFrameBuilder frame(SYN_STREAM, flags, spdy_version_, frame_size);
  frame.WriteUInt32(stream_id);
  frame.WriteUInt32(associated_stream_id);
  // Cap as appropriate.
  if (priority > GetLowestPriority()) {
    DLOG(DFATAL) << "Priority out-of-bounds.";
    priority = GetLowestPriority();
  }
  // Priority is 2 bits for <spdy3, 3 bits otherwise.
  frame.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
  frame.WriteUInt8((spdy_version_ < 3) ? 0 : credential_slot);
  WriteHeaderBlock(&frame, headers);
  DCHECK_EQ(frame.length(), frame_size);

  scoped_ptr<SpdySynStreamControlFrame> syn_frame(
      reinterpret_cast<SpdySynStreamControlFrame*>(frame.take()));
  if (compressed) {
    return reinterpret_cast<SpdySynStreamControlFrame*>(
        CompressControlFrame(*syn_frame.get(), headers));
  }
  return syn_frame.release();
}

SpdySynReplyControlFrame* SpdyFramer::CreateSynReply(
    SpdyStreamId stream_id,
    SpdyControlFlags flags,
    bool compressed,
    const SpdyHeaderBlock* headers) {
  DCHECK_GT(stream_id, 0u);
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);

  // Find our length.
  size_t frame_size = SpdySynReplyControlFrame::size() +
                      GetSerializedLength(headers);
  // In SPDY 2, there were 2 unused bytes before payload.
  if (spdy_version_ < 3) {
    frame_size += 2;
  }

  SpdyFrameBuilder frame(SYN_REPLY, flags, spdy_version_, frame_size);
  frame.WriteUInt32(stream_id);
  if (spdy_version_ < 3) {
    frame.WriteUInt16(0);  // Unused
  }
  WriteHeaderBlock(&frame, headers);
  DCHECK_EQ(frame.length(), frame_size);

  scoped_ptr<SpdySynReplyControlFrame> reply_frame(
      reinterpret_cast<SpdySynReplyControlFrame*>(frame.take()));
  if (compressed) {
    return reinterpret_cast<SpdySynReplyControlFrame*>(
        CompressControlFrame(*reply_frame.get(), headers));
  }
  return reply_frame.release();
}

SpdyRstStreamControlFrame* SpdyFramer::CreateRstStream(
    SpdyStreamId stream_id,
    SpdyStatusCodes status) const {
  DCHECK_GT(stream_id, 0u);
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
  DCHECK_NE(status, INVALID);
  DCHECK_LT(status, NUM_STATUS_CODES);

  size_t frame_size = SpdyRstStreamControlFrame::size();
  SpdyFrameBuilder frame(RST_STREAM, CONTROL_FLAG_NONE, spdy_version_,
                         frame_size);
  frame.WriteUInt32(stream_id);
  frame.WriteUInt32(status);
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyRstStreamControlFrame*>(frame.take());
}

SpdySettingsControlFrame* SpdyFramer::CreateSettings(
    const SettingsMap& values) const {
  size_t frame_size = SpdySettingsControlFrame::size() + 8 * values.size();
  SpdyFrameBuilder frame(SETTINGS, CONTROL_FLAG_NONE, spdy_version_,
                         frame_size);
  frame.WriteUInt32(values.size());
  for (SettingsMap::const_iterator it = values.begin();
       it != values.end();
       it++) {
    SettingsFlagsAndId flags_and_id(it->second.first, it->first);
    uint32 id_and_flags_wire = flags_and_id.GetWireFormat(spdy_version_);
    frame.WriteBytes(&id_and_flags_wire, 4);
    frame.WriteUInt32(it->second.second);
  }
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdySettingsControlFrame*>(frame.take());
}

SpdyPingControlFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
  size_t frame_size = SpdyPingControlFrame::size();
  SpdyFrameBuilder frame(PING, CONTROL_FLAG_NONE, spdy_version_, frame_size);
  frame.WriteUInt32(unique_id);
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyPingControlFrame*>(frame.take());
}

SpdyGoAwayControlFrame* SpdyFramer::CreateGoAway(
    SpdyStreamId last_accepted_stream_id,
    SpdyGoAwayStatus status) const {
  DCHECK_EQ(0u, last_accepted_stream_id & ~kStreamIdMask);

  // SPDY 2 GOAWAY frames are 4 bytes smaller than in SPDY 3. We account for
  // this difference via a separate offset variable, since
  // SpdyGoAwayControlFrame::size() returns the SPDY 3 size.
  const size_t goaway_offset = (protocol_version() < 3) ? 4 : 0;
  size_t frame_size = SpdyGoAwayControlFrame::size() - goaway_offset;
  SpdyFrameBuilder frame(GOAWAY, CONTROL_FLAG_NONE, spdy_version_, frame_size);
  frame.WriteUInt32(last_accepted_stream_id);
  if (protocol_version() >= 3) {
    frame.WriteUInt32(status);
  }
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyGoAwayControlFrame*>(frame.take());
}

SpdyHeadersControlFrame* SpdyFramer::CreateHeaders(
    SpdyStreamId stream_id,
    SpdyControlFlags flags,
    bool compressed,
    const SpdyHeaderBlock* headers) {
  // Basically the same as CreateSynReply().
  DCHECK_GT(stream_id, 0u);
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);

  // Find our length.
  size_t frame_size = SpdyHeadersControlFrame::size() +
                      GetSerializedLength(headers);
  // In SPDY 2, there were 2 unused bytes before payload.
  if (spdy_version_ < 3) {
    frame_size += 2;
  }

  SpdyFrameBuilder frame(HEADERS, flags, spdy_version_, frame_size);
  frame.WriteUInt32(stream_id);
  if (spdy_version_ < 3) {
    frame.WriteUInt16(0);  // Unused
  }
  WriteHeaderBlock(&frame, headers);
  DCHECK_EQ(frame.length(), frame_size);

  scoped_ptr<SpdyHeadersControlFrame> headers_frame(
      reinterpret_cast<SpdyHeadersControlFrame*>(frame.take()));
  if (compressed) {
    return reinterpret_cast<SpdyHeadersControlFrame*>(
        CompressControlFrame(*headers_frame.get(), headers));
  }
  return headers_frame.release();
}

SpdyWindowUpdateControlFrame* SpdyFramer::CreateWindowUpdate(
    SpdyStreamId stream_id,
    uint32 delta_window_size) const {
  DCHECK_GT(stream_id, 0u);
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
  DCHECK_GT(delta_window_size, 0u);
  DCHECK_LE(delta_window_size,
            static_cast<uint32>(kSpdyStreamMaximumWindowSize));

  size_t frame_size = SpdyWindowUpdateControlFrame::size();
  SpdyFrameBuilder frame(WINDOW_UPDATE, CONTROL_FLAG_NONE, spdy_version_,
                         frame_size);
  frame.WriteUInt32(stream_id);
  frame.WriteUInt32(delta_window_size);
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyWindowUpdateControlFrame*>(frame.take());
}

SpdyCredentialControlFrame* SpdyFramer::CreateCredentialFrame(
    const SpdyCredential& credential) const {
  // Calculate the size of the frame by adding the size of the
  // variable length data to the size of the fixed length data.
  size_t frame_size =  SpdyCredentialControlFrame::size() +
      credential.proof.length();
  DCHECK_EQ(SpdyCredentialControlFrame::size(), 14u);
  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
       cert != credential.certs.end();
       ++cert) {
    frame_size += sizeof(uint32);  // size of the cert_length field
    frame_size += cert->length();     // size of the cert_data field
  }

  SpdyFrameBuilder frame(CREDENTIAL, CONTROL_FLAG_NONE, spdy_version_,
                         frame_size);
  frame.WriteUInt16(credential.slot);
  frame.WriteUInt32(credential.proof.size());
  frame.WriteBytes(credential.proof.c_str(), credential.proof.size());
  for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
       cert != credential.certs.end();
       ++cert) {
    frame.WriteUInt32(cert->length());
    frame.WriteBytes(cert->c_str(), cert->length());
  }
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyCredentialControlFrame*>(frame.take());
}

SpdyDataFrame* SpdyFramer::CreateDataFrame(
    SpdyStreamId stream_id,
                                           const char* data,
    uint32 len, SpdyDataFlags flags) const {
  DCHECK_EQ(0u, stream_id & ~kStreamIdMask);
  size_t frame_size = SpdyDataFrame::size() + len;
  SpdyFrameBuilder frame(stream_id, flags, frame_size);
  frame.WriteBytes(data, len);
  DCHECK_EQ(frame.length(), frame_size);
  return reinterpret_cast<SpdyDataFrame*>(frame.take());
}

// The following compression setting are based on Brian Olson's analysis. See
// https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
// for more details.
#if defined(USE_SYSTEM_ZLIB)
// System zlib is not expected to have workaround for http://crbug.com/139744,
// so disable compression in that case.
// TODO(phajdan.jr): Remove the special case when it's no longer necessary.
static const int kCompressorLevel = 0;
#else  // !defined(USE_SYSTEM_ZLIB)
static const int kCompressorLevel = 9;
#endif  // !defined(USE_SYSTEM_ZLIB)
static const int kCompressorWindowSizeInBits = 11;
static const int kCompressorMemLevel = 1;

z_stream* SpdyFramer::GetHeaderCompressor() {
  if (header_compressor_.get())
    return header_compressor_.get();  // Already initialized.

  header_compressor_.reset(new z_stream);
  memset(header_compressor_.get(), 0, sizeof(z_stream));

  int success = deflateInit2(header_compressor_.get(),
                             kCompressorLevel,
                             Z_DEFLATED,
                             kCompressorWindowSizeInBits,
                             kCompressorMemLevel,
                             Z_DEFAULT_STRATEGY);
  if (success == Z_OK) {
    const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
                                                 : kV3Dictionary;
    const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
                                                    : kV3DictionarySize;
    success = deflateSetDictionary(header_compressor_.get(),
                                   reinterpret_cast<const Bytef*>(dictionary),
                                   dictionary_size);
  }
  if (success != Z_OK) {
    LOG(WARNING) << "deflateSetDictionary failure: " << success;
    header_compressor_.reset(NULL);
    return NULL;
  }
  return header_compressor_.get();
}

z_stream* SpdyFramer::GetHeaderDecompressor() {
  if (header_decompressor_.get())
    return header_decompressor_.get();  // Already initialized.

  header_decompressor_.reset(new z_stream);
  memset(header_decompressor_.get(), 0, sizeof(z_stream));

  int success = inflateInit(header_decompressor_.get());
  if (success != Z_OK) {
    LOG(WARNING) << "inflateInit failure: " << success;
    header_decompressor_.reset(NULL);
    return NULL;
  }
  return header_decompressor_.get();
}

bool SpdyFramer::GetFrameBoundaries(const SpdyFrame& frame,
                                    int* payload_length,
                                    int* header_length,
                                    const char** payload) const {
  size_t frame_size;
  if (frame.is_control_frame()) {
    const SpdyControlFrame& control_frame =
        reinterpret_cast<const SpdyControlFrame&>(frame);
    switch (control_frame.type()) {
      case SYN_STREAM:
        {
          const SpdySynStreamControlFrame& syn_frame =
              reinterpret_cast<const SpdySynStreamControlFrame&>(frame);
          frame_size = SpdySynStreamControlFrame::size();
          *payload_length = syn_frame.header_block_len();
          *header_length = frame_size;
          *payload = frame.data() + *header_length;
        }
        break;
      case SYN_REPLY:
        {
          const SpdySynReplyControlFrame& syn_frame =
              reinterpret_cast<const SpdySynReplyControlFrame&>(frame);
          frame_size = SpdySynReplyControlFrame::size();
          *payload_length = syn_frame.header_block_len();
          *header_length = frame_size;
          *payload = frame.data() + *header_length;
          // SPDY 2 had two bytes of unused space preceeding payload.
          if (spdy_version_ < 3) {
            *header_length += 2;
            *payload += 2;
          }
        }
        break;
      case HEADERS:
        {
          const SpdyHeadersControlFrame& headers_frame =
              reinterpret_cast<const SpdyHeadersControlFrame&>(frame);
          frame_size = SpdyHeadersControlFrame::size();
          *payload_length = headers_frame.header_block_len();
          *header_length = frame_size;
          *payload = frame.data() + *header_length;
          // SPDY 2 had two bytes of unused space preceeding payload.
          if (spdy_version_ < 3) {
            *header_length += 2;
            *payload += 2;
          }
        }
        break;
      default:
        // TODO(mbelshe): set an error?
        return false;  // We can't compress this frame!
    }
  } else {
    frame_size = SpdyFrame::kHeaderSize;
    *header_length = frame_size;
    *payload_length = frame.length();
    *payload = frame.data() + SpdyFrame::kHeaderSize;
  }
  return true;
}

SpdyControlFrame* SpdyFramer::CompressControlFrame(
    const SpdyControlFrame& frame,
    const SpdyHeaderBlock* headers) {
  z_stream* compressor = GetHeaderCompressor();
  if (!compressor)
    return NULL;

  int payload_length;
  int header_length;
  const char* payload;

  base::StatsCounter compressed_frames("spdy.CompressedFrames");
  base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
  base::StatsCounter post_compress_bytes("spdy.PostCompressSize");

  if (!enable_compression_)
    return reinterpret_cast<SpdyControlFrame*>(DuplicateFrame(frame));

  if (!GetFrameBoundaries(frame, &payload_length, &header_length, &payload))
    return NULL;

  // Create an output frame.
  int compressed_max_size = deflateBound(compressor, payload_length);
  // Since we'll be performing lots of flushes when compressing the data,
  // zlib's lower bounds may be insufficient.
  compressed_max_size *= 2;

  size_t new_frame_size = header_length + compressed_max_size;
  if ((frame.type() == SYN_REPLY || frame.type() == HEADERS) &&
      spdy_version_ < 3) {
    new_frame_size += 2;
  }
  DCHECK_GE(new_frame_size, frame.length() + SpdyFrame::kHeaderSize);
  scoped_ptr<SpdyControlFrame> new_frame(new SpdyControlFrame(new_frame_size));
  memcpy(new_frame->data(), frame.data(),
         frame.length() + SpdyFrame::kHeaderSize);

  // TODO(phajdan.jr): Clean up after we no longer need
  // to workaround http://crbug.com/139744.
#if defined(USE_SYSTEM_ZLIB)
  compressor->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(payload));
  compressor->avail_in = payload_length;
#endif  // defined(USE_SYSTEM_ZLIB)
  compressor->next_out = reinterpret_cast<Bytef*>(new_frame->data()) +
                          header_length;
  compressor->avail_out = compressed_max_size;
  // TODO(phajdan.jr): Clean up after we no longer need
  // to workaround http://crbug.com/139744.
#if defined(USE_SYSTEM_ZLIB)
  int rv = deflate(compressor, Z_SYNC_FLUSH);
  if (rv != Z_OK) {  // How can we know that it compressed everything?
    // This shouldn't happen, right?
    LOG(WARNING) << "deflate failure: " << rv;
    return NULL;
  }
#else  // !defined(USE_SYSTEM_ZLIB)
  WriteHeaderBlockToZ(headers, compressor);
#endif  // !defined(USE_SYSTEM_ZLIB)
  int compressed_size = compressed_max_size - compressor->avail_out;

  // We trust zlib. Also, we can't do anything about it.
  // See http://www.zlib.net/zlib_faq.html#faq36
  (void)VALGRIND_MAKE_MEM_DEFINED(new_frame->data() + header_length,
                                  compressed_size);

  new_frame->set_length(
      header_length + compressed_size - SpdyFrame::kHeaderSize);

  pre_compress_bytes.Add(payload_length);
  post_compress_bytes.Add(new_frame->length());

  compressed_frames.Increment();

  if (visitor_)
    visitor_->OnControlFrameCompressed(frame, *new_frame);

  return new_frame.release();
}

// Incrementally decompress the control frame's header block, feeding the
// result to the visitor in chunks. Continue this until the visitor
// indicates that it cannot process any more data, or (more commonly) we
// run out of data to deliver.
bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
    const SpdyControlFrame* control_frame,
    const char* data,
    size_t len) {
  // Get a decompressor or set error.
  z_stream* decomp = GetHeaderDecompressor();
  if (decomp == NULL) {
    LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
    set_error(SPDY_DECOMPRESS_FAILURE);
    return false;
  }

  bool processed_successfully = true;
  char buffer[kHeaderDataChunkMaxSize];

  decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
  decomp->avail_in = len;
  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
  DCHECK_LT(0u, stream_id);
  while (decomp->avail_in > 0 && processed_successfully) {
    decomp->next_out = reinterpret_cast<Bytef*>(buffer);
    decomp->avail_out = arraysize(buffer);

    int rv = inflate(decomp, Z_SYNC_FLUSH);
    if (rv == Z_NEED_DICT) {
      const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
                                                   : kV3Dictionary;
      const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
                                                      : kV3DictionarySize;
      const DictionaryIds& ids = g_dictionary_ids.Get();
      const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id
                                                      : ids.v3_dictionary_id;
      // Need to try again with the right dictionary.
      if (decomp->adler == dictionary_id) {
        rv = inflateSetDictionary(decomp,
                                  reinterpret_cast<const Bytef*>(dictionary),
                                  dictionary_size);
        if (rv == Z_OK)
          rv = inflate(decomp, Z_SYNC_FLUSH);
      }
    }

    // Inflate will generate a Z_BUF_ERROR if it runs out of input
    // without producing any output.  The input is consumed and
    // buffered internally by zlib so we can detect this condition by
    // checking if avail_in is 0 after the call to inflate.
    bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
    if ((rv == Z_OK) || input_exhausted) {
      size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
      if (decompressed_len > 0) {
        processed_successfully = visitor_->OnControlFrameHeaderData(
            stream_id, buffer, decompressed_len);
      }
      if (!processed_successfully) {
        // Assume that the problem was the header block was too large for the
        // visitor.
        set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
      }
    } else {
      DLOG(WARNING) << "inflate failure: " << rv << " " << len;
      set_error(SPDY_DECOMPRESS_FAILURE);
      processed_successfully = false;
    }
  }
  return processed_successfully;
}

bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
    const SpdyControlFrame* control_frame, const char* data, size_t len) {
  bool read_successfully = true;
  const SpdyStreamId stream_id = GetControlFrameStreamId(control_frame);
  while (read_successfully && len > 0) {
    size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
    read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
                                                           bytes_to_deliver);
    data += bytes_to_deliver;
    len -= bytes_to_deliver;
    if (!read_successfully) {
      // Assume that the problem was the header block was too large for the
      // visitor.
      set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    }
  }
  return read_successfully;
}

SpdyFrame* SpdyFramer::DuplicateFrame(const SpdyFrame& frame) {
  int size = SpdyFrame::kHeaderSize + frame.length();
  SpdyFrame* new_frame = new SpdyFrame(size);
  memcpy(new_frame->data(), frame.data(), size);
  return new_frame;
}

bool SpdyFramer::IsCompressible(const SpdyFrame& frame) const {
  // The important frames to compress are those which contain large
  // amounts of compressible data - namely the headers in the SYN_STREAM
  // and SYN_REPLY.
  if (frame.is_control_frame()) {
    const SpdyControlFrame& control_frame =
        reinterpret_cast<const SpdyControlFrame&>(frame);
    return control_frame.type() == SYN_STREAM ||
        control_frame.type() == SYN_REPLY ||
        control_frame.type() == HEADERS;
  }

  // We don't compress Data frames.
  return false;
}

size_t SpdyFramer::GetMinimumControlFrameSize(int version,
                                              SpdyControlType type) {
  switch (type) {
    case SYN_STREAM:
      return SpdySynStreamControlFrame::size();
    case SYN_REPLY:
      return SpdySynReplyControlFrame::size();
    case RST_STREAM:
      return SpdyRstStreamControlFrame::size();
    case SETTINGS:
      return SpdySettingsControlFrame::size();
    case NOOP:
      // Even though NOOP is no longer supported, we still correctly report its
      // size so that it can be handled correctly as incoming data if
      // implementations so desire.
      return SpdyFrame::kHeaderSize;
    case PING:
      return SpdyPingControlFrame::size();
    case GOAWAY:
      if (version < 3) {
        // SPDY 2 GOAWAY is smaller by 32 bits. Since
        // SpdyGoAwayControlFrame::size() returns the size for SPDY 3, we adjust
        // before returning here.
        return SpdyGoAwayControlFrame::size() - 4;
      } else {
        return SpdyGoAwayControlFrame::size();
      }
    case HEADERS:
      return SpdyHeadersControlFrame::size();
    case WINDOW_UPDATE:
      return SpdyWindowUpdateControlFrame::size();
    case CREDENTIAL:
      return SpdyCredentialControlFrame::size();
    case NUM_CONTROL_FRAME_TYPES:
      break;
  }
  LOG(ERROR) << "Unknown control frame type " << type;
  return std::numeric_limits<size_t>::max();
}

/* static */
SpdyStreamId SpdyFramer::GetControlFrameStreamId(
    const SpdyControlFrame* control_frame) {
  SpdyStreamId stream_id = kInvalidStream;
  if (control_frame != NULL) {
    switch (control_frame->type()) {
      case SYN_STREAM:
        stream_id = reinterpret_cast<const SpdySynStreamControlFrame*>(
            control_frame)->stream_id();
        break;
      case SYN_REPLY:
        stream_id = reinterpret_cast<const SpdySynReplyControlFrame*>(
            control_frame)->stream_id();
        break;
      case HEADERS:
        stream_id = reinterpret_cast<const SpdyHeadersControlFrame*>(
            control_frame)->stream_id();
        break;
      case RST_STREAM:
        stream_id = reinterpret_cast<const SpdyRstStreamControlFrame*>(
            control_frame)->stream_id();
        break;
      case WINDOW_UPDATE:
        stream_id = reinterpret_cast<const SpdyWindowUpdateControlFrame*>(
            control_frame)->stream_id();
        break;
      // All of the following types are not part of a particular stream.
      // They all fall through to the invalid control frame type case.
      // (The default case isn't used so that the compile will break if a new
      // control frame type is added but not included here.)
      case SETTINGS:
      case NOOP:
      case PING:
      case GOAWAY:
      case CREDENTIAL:
      case NUM_CONTROL_FRAME_TYPES:  // makes compiler happy
        break;
    }
  }
  return stream_id;
}

void SpdyFramer::set_enable_compression(bool value) {
  enable_compression_ = value;
}

}  // namespace net
