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

#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"
#include "third_party/zlib/zlib.h"

using base::StringPiece;
using std::string;
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;

// Used to indicate no flags in a SPDY flags field.
const uint8 kNoFlags = 0;

// Wire sizes of priority payloads.
const size_t kPriorityDependencyPayloadSize = 4;
const size_t kPriorityWeightPayloadSize = 1;

}  // namespace

const SpdyStreamId SpdyFramer::kInvalidStream = -1;
const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
// largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
// calculation details.
const size_t SpdyFramer::kControlFrameBufferSize = 18;

#ifdef DEBUG_SPDY_STATE_CHANGES
#define CHANGE_STATE(newstate)                                  \
  do {                                                          \
    DVLOG(1) << "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(
    SpdyMajorVersion version, uint32 wire) {
  if (version < SPDY3) {
    ConvertFlagsAndIdForSpdy2(&wire);
  }
  return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
}

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

uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
    const {
  uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
  if (version < SPDY3) {
    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]);
}

SpdyAltSvcScratch::SpdyAltSvcScratch() { Reset(); }
SpdyAltSvcScratch::~SpdyAltSvcScratch() {}

bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
                                                   size_t len) {
  return true;
}

bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
    const char* rst_stream_data,
    size_t len) {
  return true;
}

SpdyFramer::SpdyFramer(SpdyMajorVersion version)
    : current_frame_buffer_(new char[kControlFrameBufferSize]),
      enable_compression_(true),
      visitor_(NULL),
      debug_visitor_(NULL),
      display_protocol_("SPDY"),
      spdy_version_(version),
      syn_frame_processed_(false),
      probable_http_response_(false),
      expect_continuation_(0),
      end_stream_when_done_(false) {
  DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
  DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
  Reset();
}

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_length_ = 0;
  remaining_control_header_ = 0;
  current_frame_buffer_length_ = 0;
  current_frame_type_ = DATA;
  current_frame_flags_ = 0;
  current_frame_length_ = 0;
  current_frame_stream_id_ = kInvalidStream;
  settings_scratch_.Reset();
  altsvc_scratch_.Reset();
  remaining_padding_payload_length_ = 0;
  remaining_padding_length_fields_ = 0;
}

size_t SpdyFramer::GetDataFrameMinimumSize() const {
  return SpdyConstants::GetDataFrameMinimumSize();
}

// Size, in bytes, of the control frame header.
size_t SpdyFramer::GetControlFrameHeaderSize() const {
  return SpdyConstants::GetControlFrameHeaderSize(protocol_version());
}

size_t SpdyFramer::GetSynStreamMinimumSize() const {
  // Size, in bytes, of a SYN_STREAM frame not including the variable-length
  // name-value block.
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 2 * 4 (stream IDs) + 1 (priority)
    // + 1 (unused, was credential slot)
    return GetControlFrameHeaderSize() + 10;
  } else {
    return GetControlFrameHeaderSize() +
        kPriorityDependencyPayloadSize +
        kPriorityWeightPayloadSize;
  }
}

size_t SpdyFramer::GetSynReplyMinimumSize() const {
  // Size, in bytes, of a SYN_REPLY frame not including the variable-length
  // name-value block.
  size_t size = GetControlFrameHeaderSize();
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 4 (stream IDs)
    size += 4;
  }

  // In SPDY 2, there were 2 unused bytes before payload.
  if (protocol_version() < SPDY3) {
    size += 2;
  }

  return size;
}

size_t SpdyFramer::GetRstStreamMinimumSize() const {
  // Size, in bytes, of a RST_STREAM frame.
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 4 (stream id) + 4 (status code)
    return GetControlFrameHeaderSize() + 8;
  } else {
    // Calculated as:
    // frame prefix + 4 (status code)
    return GetControlFrameHeaderSize() + 4;
  }
}

size_t SpdyFramer::GetSettingsMinimumSize() const {
  // Size, in bytes, of a SETTINGS frame not including the IDs and values
  // from the variable-length value block. Calculated as:
  // control frame header + 4 (number of ID/value pairs)
  if (protocol_version() <= SPDY3) {
    return GetControlFrameHeaderSize() + 4;
  } else {
    return GetControlFrameHeaderSize();
  }
}

size_t SpdyFramer::GetPingSize() const {
  // Size, in bytes, of this PING frame.
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 4 (id)
    return GetControlFrameHeaderSize() + 4;
  } else {
    // Calculated as:
    // control frame header + 8 (id)
    return GetControlFrameHeaderSize() + 8;
  }
}

size_t SpdyFramer::GetGoAwayMinimumSize() const {
  // Size, in bytes, of this GOAWAY frame. Calculated as:
  // 1. Control frame header size
  size_t size = GetControlFrameHeaderSize();

  // 2. Last good stream id (4 bytes)
  size += 4;

  // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
  if (protocol_version() >= SPDY3) {
    size += 4;
  }

  return size;
}

size_t SpdyFramer::GetHeadersMinimumSize() const  {
  // Size, in bytes, of a HEADERS frame not including the variable-length
  // name-value block.
  size_t size = GetControlFrameHeaderSize();
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 4 (stream IDs)
    size += 4;
  }

  // In SPDY 2, there were 2 unused bytes before payload.
  if (protocol_version() <= SPDY2) {
    size += 2;
  }

  return size;
}

size_t SpdyFramer::GetWindowUpdateSize() const {
  // Size, in bytes, of a WINDOW_UPDATE frame.
  if (protocol_version() <= SPDY3) {
    // Calculated as:
    // control frame header + 4 (stream id) + 4 (delta)
    return GetControlFrameHeaderSize() + 8;
  } else {
    // Calculated as:
    // frame prefix + 4 (delta)
    return GetControlFrameHeaderSize() + 4;
  }
}

size_t SpdyFramer::GetBlockedSize() const {
  DCHECK_LT(SPDY3, protocol_version());
  // Size, in bytes, of a BLOCKED frame.
  // The BLOCKED frame has no payload beyond the control frame header.
  return GetControlFrameHeaderSize();
}

size_t SpdyFramer::GetPushPromiseMinimumSize() const {
  DCHECK_LT(SPDY3, protocol_version());
  // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
  // Calculated as frame prefix + 4 (promised stream id).
  return GetControlFrameHeaderSize() + 4;
}

size_t SpdyFramer::GetContinuationMinimumSize() const {
  // Size, in bytes, of a CONTINUATION frame not including the variable-length
  // headers fragments.
  return GetControlFrameHeaderSize();
}

size_t SpdyFramer::GetAltSvcMinimumSize() const {
  // Size, in bytes, of an ALTSVC frame not including the Protocol-ID, Host, and
  // (optional) Origin fields, all of which can vary in length.
  // Note that this gives a lower bound on the frame size rather than a true
  // minimum; the actual frame should always be larger than this.
  // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte)
  // + 1 (pid_len) + 1 (host_len).
  return GetControlFrameHeaderSize() + 9;
}

size_t SpdyFramer::GetPrioritySize() const {
  // Size, in bytes, of a PRIORITY frame.
  return GetControlFrameHeaderSize() +
      kPriorityDependencyPayloadSize +
      kPriorityWeightPayloadSize;
}

size_t SpdyFramer::GetFrameMinimumSize() const {
  return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
}

size_t SpdyFramer::GetFrameMaximumSize() const {
  return SpdyConstants::GetFrameMaximumSize(protocol_version());
}

size_t SpdyFramer::GetDataFrameMaximumPayload() const {
  return GetFrameMaximumSize() - GetDataFrameMinimumSize();
}

size_t SpdyFramer::GetPrefixLength(SpdyFrameType type) const {
  return SpdyConstants::GetPrefixLength(type, protocol_version());
}

const char* SpdyFramer::StateToString(int state) {
  switch (state) {
    case SPDY_ERROR:
      return "ERROR";
    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_READ_PADDING_LENGTH:
      return "SPDY_READ_PADDING_LENGTH";
    case SPDY_CONSUME_PADDING:
      return "SPDY_CONSUME_PADDING";
    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_GOAWAY_FRAME_PAYLOAD:
      return "SPDY_GOAWAY_FRAME_PAYLOAD";
    case SPDY_RST_STREAM_FRAME_PAYLOAD:
      return "SPDY_RST_STREAM_FRAME_PAYLOAD";
    case SPDY_SETTINGS_FRAME_PAYLOAD:
      return "SPDY_SETTINGS_FRAME_PAYLOAD";
    case SPDY_ALTSVC_FRAME_PAYLOAD:
      return "SPDY_ALTSVC_FRAME_PAYLOAD";
  }
  return "UNKNOWN_STATE";
}

void SpdyFramer::set_error(SpdyError error) {
  DCHECK(visitor_);
  error_code_ = error;
  // These values will usually get reset once we come to the end
  // of a header block, but if we run into an error that
  // might not happen, so reset them here.
  expect_continuation_ = 0;
  end_stream_when_done_ = false;

  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";
    case SPDY_INVALID_CONTROL_FRAME_FLAGS:
      return "SPDY_INVALID_CONTROL_FRAME_FLAGS";
    case SPDY_UNEXPECTED_FRAME:
      return "UNEXPECTED_FRAME";
  }
  return "UNKNOWN_ERROR";
}

const char* SpdyFramer::StatusCodeToString(int status_code) {
  switch (status_code) {
    case RST_STREAM_INVALID:
      return "INVALID";
    case RST_STREAM_PROTOCOL_ERROR:
      return "PROTOCOL_ERROR";
    case RST_STREAM_INVALID_STREAM:
      return "INVALID_STREAM";
    case RST_STREAM_REFUSED_STREAM:
      return "REFUSED_STREAM";
    case RST_STREAM_UNSUPPORTED_VERSION:
      return "UNSUPPORTED_VERSION";
    case RST_STREAM_CANCEL:
      return "CANCEL";
    case RST_STREAM_INTERNAL_ERROR:
      return "INTERNAL_ERROR";
    case RST_STREAM_FLOW_CONTROL_ERROR:
      return "FLOW_CONTROL_ERROR";
    case RST_STREAM_STREAM_IN_USE:
      return "STREAM_IN_USE";
    case RST_STREAM_STREAM_ALREADY_CLOSED:
      return "STREAM_ALREADY_CLOSED";
    case RST_STREAM_INVALID_CREDENTIALS:
      return "INVALID_CREDENTIALS";
    case RST_STREAM_FRAME_TOO_LARGE:
      return "FRAME_TOO_LARGE";
    case RST_STREAM_CONNECT_ERROR:
      return "CONNECT_ERROR";
    case RST_STREAM_ENHANCE_YOUR_CALM:
      return "ENHANCE_YOUR_CALM";
  }
  return "UNKNOWN_STATUS";
}

const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
  switch (type) {
    case DATA:
      return "DATA";
    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 BLOCKED:
      return "BLOCKED";
    case PUSH_PROMISE:
      return "PUSH_PROMISE";
    case CONTINUATION:
      return "CONTINUATION";
    case ALTSVC:
      return "ALTSVC";
    case PRIORITY:
      return "PRIORITY";
  }
  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:
        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, PUSH_PROMISE, CONTINUATION)
        // 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, protocol_version() > SPDY3);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

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

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

      case SPDY_ALTSVC_FRAME_PAYLOAD: {
        size_t bytes_read = ProcessAltSvcFramePayload(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_READ_PADDING_LENGTH: {
        size_t bytes_read = ProcessFramePaddingLength(data, len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

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

      case SPDY_IGNORE_REMAINING_PAYLOAD: {
        size_t bytes_read = ProcessIgnoredControlFramePayload(/*data,*/ len);
        len -= bytes_read;
        data += bytes_read;
        break;
      }

      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_buffer_length_ == 0 &&
      remaining_data_length_ == 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;

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

  if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
    // Not enough information to do anything meaningful.
    return original_len - len;
  }

  // Using a scoped_ptr here since we may need to create a new SpdyFrameReader
  // when processing DATA frames below.
  scoped_ptr<SpdyFrameReader> reader(
      new SpdyFrameReader(current_frame_buffer_.get(),
                          current_frame_buffer_length_));

  uint16 version = 0;
  bool is_control_frame = false;

  uint16 control_frame_type_field = DATA;
  // ProcessControlFrameHeader() will set current_frame_type_ to the
  // correct value if this is a valid control frame.
  current_frame_type_ = DATA;
  if (protocol_version() <= SPDY3) {
    bool successful_read = reader->ReadUInt16(&version);
    DCHECK(successful_read);
    is_control_frame = (version & kControlFlagMask) != 0;
    version &= ~kControlFlagMask;  // Only valid for control frames.
    if (is_control_frame) {
      // We check version before we check validity: version can never be
      // 'invalid', it can only be unsupported.
      if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) ||
          version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) ||
          SpdyConstants::ParseMajorVersion(version) != protocol_version()) {
        // Version does not match the version the framer was initialized with.
        DVLOG(1) << "Unsupported SPDY version "
                 << version
                 << " (expected " << protocol_version() << ")";
        set_error(SPDY_UNSUPPORTED_VERSION);
        return 0;
      } else {
        // Convert version from wire format to SpdyMajorVersion.
        version = SpdyConstants::ParseMajorVersion(version);
      }
      // We check control_frame_type_field's validity in
      // ProcessControlFrameHeader().
      successful_read = reader->ReadUInt16(&control_frame_type_field);
    } else {
      reader->Rewind();
      successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    }
    DCHECK(successful_read);

    successful_read = reader->ReadUInt8(&current_frame_flags_);
    DCHECK(successful_read);

    uint32 length_field = 0;
    successful_read = reader->ReadUInt24(&length_field);
    DCHECK(successful_read);
    remaining_data_length_ = length_field;
    current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed();
  } else {
    version = protocol_version();
    uint16 length_field = 0;
    bool successful_read = reader->ReadUInt16(&length_field);
    DCHECK(successful_read);

    uint8 control_frame_type_field_uint8 = DATA;
    successful_read = reader->ReadUInt8(&control_frame_type_field_uint8);
    DCHECK(successful_read);
    // We check control_frame_type_field's validity in
    // ProcessControlFrameHeader().
    control_frame_type_field = control_frame_type_field_uint8;
    is_control_frame = (control_frame_type_field != DATA);

    if (is_control_frame) {
      current_frame_length_ = length_field + GetControlFrameHeaderSize();
    } else {
      current_frame_length_ = length_field + GetDataFrameMinimumSize();
    }

    successful_read = reader->ReadUInt8(&current_frame_flags_);
    DCHECK(successful_read);

    successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    DCHECK(successful_read);

    remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed();

    // Before we accept a DATA frame, we need to make sure we're not in the
    // middle of processing a header block.
    const bool is_continuation_frame = (control_frame_type_field ==
        SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION));
    if ((expect_continuation_ != 0) != is_continuation_frame) {
      if (expect_continuation_ != 0) {
        DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION "
                    << "frame, but instead received frame type "
                    << control_frame_type_field;
      } else {
        DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame.";
      }
      set_error(SPDY_UNEXPECTED_FRAME);
      return original_len - len;
    }
  }
  DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize()
                             : GetDataFrameMinimumSize(),
            reader->GetBytesConsumed());
  DCHECK_EQ(current_frame_length_,
            remaining_data_length_ + reader->GetBytesConsumed());

  // This is just a sanity check for help debugging early frame errors.
  if (remaining_data_length_ > 1000000u) {
    // The strncmp for 5 is safe because we only hit this point if we
    // have kMinCommonHeader (8) bytes
    if (!syn_frame_processed_ &&
        strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
      LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_
                   << " 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 (!is_control_frame) {
    if (protocol_version() > SPDY3) {
      // Catch bogus tests sending oversized DATA frames.
      DCHECK_GE(GetFrameMaximumSize(), current_frame_length_)
          << "DATA frame too large for SPDY >= 4.";
    }

    uint8 valid_data_flags = 0;
    if (protocol_version() > SPDY3) {
      valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
          DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH;
    } else {
      valid_data_flags = DATA_FLAG_FIN;
    }

    if (current_frame_flags_ & ~valid_data_flags) {
      set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
    } else {
      visitor_->OnDataFrameHeader(current_frame_stream_id_,
                                  remaining_data_length_,
                                  current_frame_flags_ & DATA_FLAG_FIN);
      if (remaining_data_length_ > 0) {
        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
      } else {
        // Empty data frame.
        if (current_frame_flags_ & DATA_FLAG_FIN) {
          visitor_->OnStreamFrameData(
              current_frame_stream_id_, NULL, 0, true);
        }
        CHANGE_STATE(SPDY_AUTO_RESET);
      }
    }
  } else {
    ProcessControlFrameHeader(control_frame_type_field);
  }

  return original_len - len;
}

void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
  DCHECK_EQ(SPDY_NO_ERROR, error_code_);
  DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);

  // Early detection of deprecated frames that we ignore.
  if (protocol_version() <= SPDY3) {
    if (control_frame_type_field == NOOP) {
      current_frame_type_ = NOOP;
      DVLOG(1) << "NOOP control frame found. Ignoring.";
      CHANGE_STATE(SPDY_AUTO_RESET);
      return;
    }

    if (control_frame_type_field == CREDENTIAL) {
      current_frame_type_ = CREDENTIAL;
      DCHECK_EQ(SPDY3, protocol_version());
      DVLOG(1) << "CREDENTIAL control frame found. Ignoring.";
      CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
      return;
    }
  }

  if (!SpdyConstants::IsValidFrameType(protocol_version(),
                                       control_frame_type_field)) {
    DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field
                  << " (protocol version: " << protocol_version() << ")";
    set_error(SPDY_INVALID_CONTROL_FRAME);
    return;
  }

  current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(),
                                                      control_frame_type_field);

  // Do some sanity checking on the control frame sizes and flags.
  switch (current_frame_type_) {
    case SYN_STREAM:
      if (current_frame_length_ < GetSynStreamMinimumSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ &
                 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case SYN_REPLY:
      if (current_frame_length_ < GetSynReplyMinimumSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case RST_STREAM:
      // For SPDY versions < 4, the header has a fixed length.
      // For SPDY version 4 and up, the RST_STREAM frame may include optional
      // opaque data, so we only have a lower limit on the frame size.
      if ((current_frame_length_ != GetRstStreamMinimumSize() &&
           protocol_version() <= SPDY3) ||
          (current_frame_length_ < GetRstStreamMinimumSize() &&
           protocol_version() > SPDY3)) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case SETTINGS:
    {
      // Make sure that we have an integral number of 8-byte key/value pairs,
      // plus a 4-byte length field in SPDY3 and below.
      size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0);
      // Size of each key/value pair in bytes.
      size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
      if (current_frame_length_ < GetSettingsMinimumSize() ||
          (current_frame_length_ - GetControlFrameHeaderSize())
          % setting_size != values_prefix_size) {
        DLOG(WARNING) << "Invalid length for SETTINGS frame: "
                      << current_frame_length_;
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (protocol_version() <= SPDY3 &&
                 current_frame_flags_ &
                 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      } else if (protocol_version() > SPDY3 &&
                 current_frame_flags_ & ~SETTINGS_FLAG_ACK) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      } else if (protocol_version() > SPDY3 &&
                 current_frame_flags_ & SETTINGS_FLAG_ACK &&
                 current_frame_length_ > GetSettingsMinimumSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      }
      break;
    }
    case PING:
      if (current_frame_length_ != GetPingSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) ||
                 (current_frame_flags_ & ~PING_FLAG_ACK)) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case GOAWAY:
      {
        // For SPDY version < 4, there are only mandatory fields and the header
        // has a fixed length. For SPDY version >= 4, optional opaque data may
        // be appended to the GOAWAY frame, thus there is only a minimal length
        // restriction.
        if ((current_frame_length_ != GetGoAwayMinimumSize() &&
             protocol_version() <= SPDY3) ||
            (current_frame_length_ < GetGoAwayMinimumSize() &&
             protocol_version() > SPDY3)) {
          set_error(SPDY_INVALID_CONTROL_FRAME);
        } else if (current_frame_flags_ != 0) {
          set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
        }
        break;
      }
    case HEADERS:
      {
        size_t min_size = GetHeadersMinimumSize();
        if (protocol_version() > SPDY3 &&
            (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
          min_size += 4;
        }
        if (current_frame_length_ < min_size) {
          set_error(SPDY_INVALID_CONTROL_FRAME);
        } else if (protocol_version() <= SPDY3 &&
                   current_frame_flags_ & ~CONTROL_FLAG_FIN) {
          set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
        } else if (protocol_version() > SPDY3 &&
                   current_frame_flags_ &
                       ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
                         HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT |
                         HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
          set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
        }
      }
      break;
    case WINDOW_UPDATE:
      if (current_frame_length_ != GetWindowUpdateSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case BLOCKED:
      if (current_frame_length_ != GetBlockedSize() ||
          protocol_version() <= SPDY3) {
        // TODO(mlavan): BLOCKED frames are no longer part of SPDY4.
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case PUSH_PROMISE:
      if (current_frame_length_ < GetPushPromiseMinimumSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      } else if (protocol_version() > SPDY3 &&
                 current_frame_flags_ &
                     ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE |
                       HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case CONTINUATION:
      if (current_frame_length_ < GetContinuationMinimumSize() ||
          protocol_version() <= SPDY3) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ &
                 ~(HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PAD_LOW |
                   HEADERS_FLAG_PAD_HIGH)) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case ALTSVC:
      if (current_frame_length_ <= GetAltSvcMinimumSize()) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    case PRIORITY:
      if (current_frame_length_ != GetPrioritySize() ||
          protocol_version() <= SPDY3) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
      } else if (current_frame_flags_ != 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
      }
      break;
    default:
      LOG(WARNING) << "Valid " << display_protocol_
                   << " control frame with unhandled type: "
                   << current_frame_type_;
      // This branch should be unreachable because of the frame type bounds
      // check above. However, we DLOG(FATAL) here in an effort to painfully
      // club the head of the developer who failed to keep this file in sync
      // with spdy_protocol.h.
      DLOG(FATAL);
      set_error(SPDY_INVALID_CONTROL_FRAME);
      break;
  }

  if (state_ == SPDY_ERROR) {
    return;
  }

  if (current_frame_length_ > GetControlFrameBufferMaxSize()) {
    DLOG(WARNING) << "Received control frame with way too big of a payload: "
                  << current_frame_length_;
    set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    return;
  }

  if (current_frame_type_ == GOAWAY) {
    CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD);
    return;
  }

  if (current_frame_type_ == RST_STREAM) {
    CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD);
    return;
  }

  if (current_frame_type_ == ALTSVC) {
    CHANGE_STATE(SPDY_ALTSVC_FRAME_PAYLOAD);
    return;
  }
  // Determine the frame size without variable-length data.
  int32 frame_size_without_variable_data;
  switch (current_frame_type_) {
    case SYN_STREAM:
      syn_frame_processed_ = true;
      frame_size_without_variable_data = GetSynStreamMinimumSize();
      break;
    case SYN_REPLY:
      syn_frame_processed_ = true;
      frame_size_without_variable_data = GetSynReplyMinimumSize();
      break;
    case SETTINGS:
      frame_size_without_variable_data = GetSettingsMinimumSize();
      break;
    case HEADERS:
      frame_size_without_variable_data = GetHeadersMinimumSize();
      if (protocol_version() > SPDY3 &&
          current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
        frame_size_without_variable_data +=
            kPriorityDependencyPayloadSize +
            kPriorityWeightPayloadSize;
      }
      break;
    case PUSH_PROMISE:
      frame_size_without_variable_data = GetPushPromiseMinimumSize();
      break;
    case CONTINUATION:
      frame_size_without_variable_data = GetContinuationMinimumSize();
      break;
    default:
      frame_size_without_variable_data = -1;
      break;
  }

  if ((frame_size_without_variable_data == -1) &&
      (current_frame_length_ > 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_buffer_length_));
    remaining_control_header_ = frame_size_without_variable_data -
        current_frame_buffer_length_;

    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);
  if (bytes_to_read > 0) {
    DCHECK_GE(kControlFrameBufferSize,
              current_frame_buffer_length_ + bytes_to_read);
    memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
           *data,
           bytes_to_read);
    current_frame_buffer_length_ += bytes_to_read;
    *data += bytes_to_read;
    *len -= bytes_to_read;
  }
  return bytes_to_read;
}

size_t SpdyFramer::GetSerializedLength(
    const SpdyMajorVersion spdy_version,
    const SpdyHeaderBlock* headers) {
  const size_t num_name_value_pairs_size
      = (spdy_version < SPDY3) ? 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 SpdyMajorVersion spdy_version,
                                  const SpdyHeaderBlock* headers) {
  if (spdy_version < SPDY3) {
    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) {
    if (spdy_version < SPDY3) {
      frame->WriteString(it->first);
      frame->WriteString(it->second);
    } else {
      frame->WriteStringPiece32(it->first);
      frame->WriteStringPiece32(it->second);
    }
  }
}

// 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);
  }
  if (!data.empty()) {
    // If we didn't provide any data then zlib will return Z_BUF_ERROR.
    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_);
  const 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;
    remaining_data_length_ -= bytes_read;
  }

  if (remaining_control_header_ == 0) {
    SpdyFrameReader reader(current_frame_buffer_.get(),
                           current_frame_buffer_length_);
    reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.

    switch (current_frame_type_) {
      case SYN_STREAM:
        {
          DCHECK_GE(SPDY3, protocol_version());
          bool successful_read = true;
          successful_read = reader.ReadUInt31(&current_frame_stream_id_);
          DCHECK(successful_read);
          if (current_frame_stream_id_ == 0) {
            set_error(SPDY_INVALID_CONTROL_FRAME);
            break;
          }

          SpdyStreamId associated_to_stream_id = kInvalidStream;
          successful_read = reader.ReadUInt31(&associated_to_stream_id);
          DCHECK(successful_read);

          SpdyPriority priority = 0;
          successful_read = reader.ReadUInt8(&priority);
          DCHECK(successful_read);
          if (protocol_version() <= SPDY2) {
            priority = priority >> 6;
          } else {
            priority = priority >> 5;
          }

         // Seek past unused byte; used to be credential slot in SPDY 3.
         reader.Seek(1);

          DCHECK(reader.IsDoneReading());
          if (debug_visitor_) {
            debug_visitor_->OnReceiveCompressedFrame(
                current_frame_stream_id_,
                current_frame_type_,
                current_frame_length_);
          }
          visitor_->OnSynStream(
              current_frame_stream_id_,
              associated_to_stream_id,
              priority,
              (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
              (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
        }
        CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
        break;
      case SETTINGS:
        if (protocol_version() > SPDY3 &&
            current_frame_flags_ & SETTINGS_FLAG_ACK) {
          visitor_->OnSettingsAck();
          CHANGE_STATE(SPDY_AUTO_RESET);
        } else {
          visitor_->OnSettings(current_frame_flags_ &
              SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
          CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
        }
        break;
      case SYN_REPLY:
      case HEADERS:
        // SYN_REPLY and HEADERS are the same, save for the visitor call.
        {
          if (protocol_version() > SPDY3) {
            DCHECK_EQ(HEADERS, current_frame_type_);
          }
          bool successful_read = true;
          if (protocol_version() <= SPDY3) {
            successful_read = reader.ReadUInt31(&current_frame_stream_id_);
            DCHECK(successful_read);
          }
          if (current_frame_stream_id_ == 0) {
            set_error(SPDY_INVALID_CONTROL_FRAME);
            break;
          }
          if (protocol_version() <= SPDY2) {
            // SPDY 2 had two unused bytes here. Seek past them.
            reader.Seek(2);
          }
          if (protocol_version() > SPDY3 &&
             !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
             current_frame_type_ == HEADERS) {
            expect_continuation_ = current_frame_stream_id_;
            end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
          }
          const bool has_priority =
              (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
          uint32 priority = 0;
          if (protocol_version() > SPDY3 && has_priority) {
            // TODO(jgraettinger): Process dependency rather than ignoring it.
            reader.Seek(kPriorityDependencyPayloadSize);
            uint8 weight = 0;
            successful_read = reader.ReadUInt8(&weight);
            if (successful_read) {
              priority = MapWeightToPriority(weight);
            }
          }
          DCHECK(reader.IsDoneReading());
          if (debug_visitor_) {
            // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
            SpdyFrameType reported_type = current_frame_type_;
            if (protocol_version() > SPDY3 && has_priority) {
              reported_type = SYN_STREAM;
            }
            debug_visitor_->OnReceiveCompressedFrame(
                current_frame_stream_id_,
                reported_type,
                current_frame_length_);
          }
          if (current_frame_type_ == SYN_REPLY) {
            visitor_->OnSynReply(
                current_frame_stream_id_,
                (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
          } else if (protocol_version() > SPDY3 &&
              current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
            // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes
            // can be made independent of wire changes.
            visitor_->OnSynStream(
                current_frame_stream_id_,
                0,  // associated_to_stream_id
                priority,
                current_frame_flags_ & CONTROL_FLAG_FIN,
                false);  // unidirectional
          } else {
            visitor_->OnHeaders(
                current_frame_stream_id_,
                (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
                expect_continuation_ == 0);
          }
        }
        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
        break;
      case PUSH_PROMISE:
        {
          DCHECK_LT(SPDY3, protocol_version());
          if (current_frame_stream_id_ == 0) {
            set_error(SPDY_INVALID_CONTROL_FRAME);
            break;
          }
          SpdyStreamId promised_stream_id = kInvalidStream;
          bool successful_read = reader.ReadUInt31(&promised_stream_id);
          DCHECK(successful_read);
          DCHECK(reader.IsDoneReading());
          if (promised_stream_id == 0) {
            set_error(SPDY_INVALID_CONTROL_FRAME);
            break;
          }
          if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) {
            expect_continuation_ = current_frame_stream_id_;
          }
          if (debug_visitor_) {
            debug_visitor_->OnReceiveCompressedFrame(
                current_frame_stream_id_,
                current_frame_type_,
                current_frame_length_);
          }
          visitor_->OnPushPromise(current_frame_stream_id_,
                                  promised_stream_id,
                                  (current_frame_flags_ &
                                   PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
        }
        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
        break;
      case CONTINUATION:
        {
          // Check to make sure the stream id of the current frame is
          // the same as that of the preceding frame.
          // If we're at this point we should already know that
          // expect_continuation_ != 0, so this doubles as a check
          // that current_frame_stream_id != 0.
          if (current_frame_stream_id_ != expect_continuation_) {
            set_error(SPDY_INVALID_CONTROL_FRAME);
            break;
          }
          if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) {
            expect_continuation_ = 0;
          }
          if (debug_visitor_) {
            debug_visitor_->OnReceiveCompressedFrame(
                current_frame_stream_id_,
                current_frame_type_,
                current_frame_length_);
          }
          visitor_->OnContinuation(current_frame_stream_id_,
                                   (current_frame_flags_ &
                                    HEADERS_FLAG_END_HEADERS) != 0);
        }
        CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
        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,
                                                  bool is_hpack_header_block) {
  DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);

  bool processed_successfully = true;
  if (current_frame_type_ != SYN_STREAM &&
      current_frame_type_ != SYN_REPLY &&
      current_frame_type_ != HEADERS &&
      current_frame_type_ != PUSH_PROMISE &&
      current_frame_type_ != CONTINUATION) {
    LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
  }
  size_t process_bytes = std::min(
      data_len, remaining_data_length_ - remaining_padding_payload_length_);
  if (is_hpack_header_block) {
    if (!GetHpackDecoder()->HandleControlFrameHeadersData(
            current_frame_stream_id_, data, process_bytes)) {
      // TODO(jgraettinger): Finer-grained HPACK error codes.
      set_error(SPDY_DECOMPRESS_FAILURE);
      processed_successfully = false;
    }
  } else if (process_bytes > 0) {
    if (enable_compression_ && protocol_version() <= SPDY3) {
      processed_successfully = IncrementallyDecompressControlFrameHeaderData(
          current_frame_stream_id_, data, process_bytes);
    } else {
      processed_successfully = IncrementallyDeliverControlFrameHeaderData(
          current_frame_stream_id_, data, process_bytes);
    }
  }
  remaining_data_length_ -= process_bytes;

  // Handle the case that there is no futher data in this frame.
  if (remaining_data_length_ == remaining_padding_payload_length_ &&
      processed_successfully) {
    if (expect_continuation_ == 0) {
      if (is_hpack_header_block) {
        if (!GetHpackDecoder()->HandleControlFrameHeadersComplete(
                current_frame_stream_id_)) {
          set_error(SPDY_DECOMPRESS_FAILURE);
          processed_successfully = false;
        } else {
          // TODO(jgraettinger): To be removed with migration to
          // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
          // block, delivered via reentrant call to
          // ProcessControlFrameHeaderBlock().
          DeliverHpackBlockAsSpdy3Block();
          return process_bytes;
        }
      } else {
        // The complete header block has been delivered. We send a zero-length
        // OnControlFrameHeaderData() to indicate this.
        visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
      }
    }
    if (processed_successfully) {
      CHANGE_STATE(SPDY_CONSUME_PADDING);
    }
  }

  // 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_);
  DCHECK_EQ(SETTINGS, current_frame_type_);
  size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
  size_t processed_bytes = 0;

  size_t setting_size = protocol_version() <= SPDY3 ? 8 : 5;

  // 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>(setting_size - settings_scratch_.setting_buf_len));

    // Check if we have a complete setting in our input.
    if (processing == setting_size) {
      // 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 == setting_size) {
        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_data_length_ -= processed_bytes;
  if (remaining_data_length_ == 0) {
    visitor_->OnSettingsEnd();
    CHANGE_STATE(SPDY_AUTO_RESET);
  }

  return processed_bytes;
}

void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
  DCHECK_LT(SPDY3, protocol_version());
  DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);

  const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block();
  if (block.empty()) {
    // Special-case this to make tests happy.
    ProcessControlFrameHeaderBlock(NULL, 0, false);
    return;
  }
  SpdyFrameBuilder builder(
      GetSerializedLength(protocol_version(), &block),
      SPDY3);

  SerializeNameValueBlockWithoutCompression(&builder, block);
  scoped_ptr<SpdyFrame> frame(builder.take());

  // Preserve padding length, and reset it after the re-entrant call.
  size_t remaining_padding = remaining_padding_payload_length_;

  remaining_padding_payload_length_ = 0;
  remaining_data_length_ = frame->size();

  ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);

  remaining_padding_payload_length_ = remaining_padding;
  remaining_data_length_ = remaining_padding;
}

bool SpdyFramer::ProcessSetting(const char* data) {
  int id_field;
  SpdySettingsIds id;
  uint8 flags = 0;
  uint32 value;

  // Extract fields.
  // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
  if (protocol_version() <= SPDY3) {
    const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
    SettingsFlagsAndId id_and_flags =
      SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire);
    id_field = id_and_flags.id();
    flags = id_and_flags.flags();
    value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
  } else {
    id_field = *(reinterpret_cast<const uint8*>(data));
    value = ntohl(*(reinterpret_cast<const uint32*>(data + 1)));
  }

  // Validate id.
  if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) {
    DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field;
    return false;
  }
  id = SpdyConstants::ParseSettingId(protocol_version(), id_field);

  if (protocol_version() <= SPDY3) {
    // Detect duplicates.
    if (id <= settings_scratch_.last_setting_id) {
      DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
                    << " in " << display_protocol_ << " SETTINGS frame "
                    << "(last setting 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;
  size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
                                               remaining_data_length_);
  remaining_data_length_ -= bytes_read;
  if (remaining_data_length_ == 0) {
    SpdyFrameReader reader(current_frame_buffer_.get(),
                           current_frame_buffer_length_);
    reader.Seek(GetControlFrameHeaderSize());  // Skip frame header.

    // Use frame-specific handlers.
    switch (current_frame_type_) {
      case PING: {
          SpdyPingId id = 0;
          bool is_ack = protocol_version() > SPDY3 &&
              (current_frame_flags_ & PING_FLAG_ACK);
          bool successful_read = true;
          if (protocol_version() <= SPDY3) {
            uint32 id32 = 0;
            successful_read = reader.ReadUInt32(&id32);
            id = id32;
          } else {
            successful_read = reader.ReadUInt64(&id);
          }
          DCHECK(successful_read);
          DCHECK(reader.IsDoneReading());
          visitor_->OnPing(id, is_ack);
        }
        break;
      case WINDOW_UPDATE: {
          uint32 delta_window_size = 0;
          bool successful_read = true;
          if (protocol_version() <= SPDY3) {
            successful_read = reader.ReadUInt31(&current_frame_stream_id_);
            DCHECK(successful_read);
          }
          successful_read = reader.ReadUInt32(&delta_window_size);
          DCHECK(successful_read);
          DCHECK(reader.IsDoneReading());
          visitor_->OnWindowUpdate(current_frame_stream_id_,
                                   delta_window_size);
        }
        break;
      case BLOCKED: {
          DCHECK_LT(SPDY3, protocol_version());
          DCHECK(reader.IsDoneReading());
          visitor_->OnBlocked(current_frame_stream_id_);
        }
        break;
      case PRIORITY: {
          DCHECK_LT(SPDY3, protocol_version());
          // TODO(hkhalil): Process PRIORITY frames rather than ignore them.
          reader.Seek(5);
          DCHECK(reader.IsDoneReading());
        }
        break;
      default:
        // Unreachable.
        LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
    }

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

size_t SpdyFramer::ProcessGoAwayFramePayload(const char* data, size_t len) {
  if (len == 0) {
    return 0;
  }
  // Clamp to the actual remaining payload.
  if (len > remaining_data_length_) {
    len = remaining_data_length_;
  }
  size_t original_len = len;

  // Check if we had already read enough bytes to parse the GOAWAY header.
  const size_t header_size = GetGoAwayMinimumSize();
  size_t unread_header_bytes = header_size - current_frame_buffer_length_;
  bool already_parsed_header = (unread_header_bytes == 0);
  if (!already_parsed_header) {
    // Buffer the new GOAWAY header bytes we got.
    UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);

    // Do we have enough to parse the constant size GOAWAY header?
    if (current_frame_buffer_length_ == header_size) {
      // Parse out the last good stream id.
      SpdyFrameReader reader(current_frame_buffer_.get(),
                             current_frame_buffer_length_);
      reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
      bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
      DCHECK(successful_read);

      // In SPDYv3 and up, frames also specify a status code - parse it out.
      SpdyGoAwayStatus status = GOAWAY_OK;
      if (protocol_version() >= SPDY3) {
        uint32 status_raw = GOAWAY_OK;
        successful_read = reader.ReadUInt32(&status_raw);
        DCHECK(successful_read);
        if (SpdyConstants::IsValidGoAwayStatus(protocol_version(),
                                               status_raw)) {
          status = SpdyConstants::ParseGoAwayStatus(protocol_version(),
                                                    status_raw);
        } else {
          DCHECK(false);
          // Throw an error for SPDY4+, keep liberal behavior
          // for earlier versions.
          if (protocol_version() > SPDY3) {
            DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw;
            set_error(SPDY_INVALID_CONTROL_FRAME);
            return 0;
          }
        }
      }
      // Finished parsing the GOAWAY header, call frame handler.
      visitor_->OnGoAway(current_frame_stream_id_, status);
    }
  }

  // Handle remaining data as opaque.
  bool processed_successfully = true;
  if (len > 0) {
    processed_successfully = visitor_->OnGoAwayFrameData(data, len);
  }
  remaining_data_length_ -= original_len;
  if (!processed_successfully) {
    set_error(SPDY_GOAWAY_FRAME_CORRUPT);
  } else if (remaining_data_length_ == 0) {
    // Signal that there is not more opaque data.
    visitor_->OnGoAwayFrameData(NULL, 0);
    CHANGE_STATE(SPDY_AUTO_RESET);
  }
  return original_len;
}

size_t SpdyFramer::ProcessRstStreamFramePayload(const char* data, size_t len) {
  if (len == 0) {
    return 0;
  }
  // Clamp to the actual remaining payload.
  if (len > remaining_data_length_) {
    len = remaining_data_length_;
  }
  size_t original_len = len;

  // Check if we had already read enough bytes to parse the fixed-length portion
  // of the RST_STREAM frame.
  const size_t header_size = GetRstStreamMinimumSize();
  size_t unread_header_bytes = header_size - current_frame_buffer_length_;
  bool already_parsed_header = (unread_header_bytes == 0);
  if (!already_parsed_header) {
    // Buffer the new RST_STREAM header bytes we got.
    UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);

    // Do we have enough to parse the constant size RST_STREAM header?
    if (current_frame_buffer_length_ == header_size) {
      // Parse out the last good stream id.
      SpdyFrameReader reader(current_frame_buffer_.get(),
                             current_frame_buffer_length_);
      reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
      if (protocol_version() <= SPDY3) {
        bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
        DCHECK(successful_read);
      }

      SpdyRstStreamStatus status = RST_STREAM_INVALID;
      uint32 status_raw = status;
      bool successful_read = reader.ReadUInt32(&status_raw);
      DCHECK(successful_read);
      if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
                                                status_raw)) {
        status = static_cast<SpdyRstStreamStatus>(status_raw);
      } else {
        // Throw an error for SPDY4+, keep liberal behavior
        // for earlier versions.
        if (protocol_version() > SPDY3) {
          DLOG(WARNING) << "Invalid RST_STREAM status " << status_raw;
          set_error(SPDY_INVALID_CONTROL_FRAME);
          return 0;
        }
      }
      // Finished parsing the RST_STREAM header, call frame handler.
      visitor_->OnRstStream(current_frame_stream_id_, status);
    }
  }

  // Handle remaining data as opaque.
  bool processed_successfully = true;
  if (len > 0) {
    processed_successfully = visitor_->OnRstStreamFrameData(data, len);
  }
  remaining_data_length_ -= original_len;
  if (!processed_successfully) {
    set_error(SPDY_RST_STREAM_FRAME_CORRUPT);
  } else if (remaining_data_length_ == 0) {
    // Signal that there is not more opaque data.
    visitor_->OnRstStreamFrameData(NULL, 0);
    CHANGE_STATE(SPDY_AUTO_RESET);
  }
  return original_len;
}

size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) {
  if (len == 0) {
    return 0;
  }

  // Clamp to the actual remaining payload.
  len = std::min(len, remaining_data_length_);

  size_t processed_bytes = 0;
  size_t processing = 0;
  size_t bytes_remaining;
  char* buffer;
  size_t* buffer_len;

  while (len > 0) {
    if (altsvc_scratch_.pid_len == 0) {
      // The size of the frame up to the PID_LEN field.
      size_t fixed_len_portion = GetAltSvcMinimumSize() - 1;
      bytes_remaining = fixed_len_portion - current_frame_buffer_length_;
      processing = std::min(len, bytes_remaining);
      // Buffer the new ALTSVC bytes we got.
      UpdateCurrentFrameBuffer(&data, &len, processing);

      // Do we have enough to parse the length of the protocol id?
      if (current_frame_buffer_length_ == fixed_len_portion) {
        // Parse out the max age, port, and pid_len.
        SpdyFrameReader reader(current_frame_buffer_.get(),
                               current_frame_buffer_length_);
        reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
        bool successful_read = reader.ReadUInt32(&altsvc_scratch_.max_age);
        reader.ReadUInt16(&altsvc_scratch_.port);
        reader.Seek(1);  // Reserved byte.
        successful_read = successful_read &&
                          reader.ReadUInt8(&altsvc_scratch_.pid_len);
        DCHECK(successful_read);
        // Sanity check length value.
        if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len >=
            current_frame_length_) {
          set_error(SPDY_INVALID_CONTROL_FRAME);
          return 0;
        }
        altsvc_scratch_.protocol_id.reset(
            new char[size_t(altsvc_scratch_.pid_len)]);
      }
      processed_bytes += processing;
      continue;
    } else if (altsvc_scratch_.pid_buf_len < altsvc_scratch_.pid_len) {
      // Buffer protocol id field as in comes in.
      buffer = altsvc_scratch_.protocol_id.get();
      buffer_len = &altsvc_scratch_.pid_buf_len;
      bytes_remaining = altsvc_scratch_.pid_len - altsvc_scratch_.pid_buf_len;
    } else if (altsvc_scratch_.host_len == 0) {
      // Parse out the host length.
      processing = 1;
      altsvc_scratch_.host_len = *reinterpret_cast<const uint8*>(data);
      // Sanity check length value.
      if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len +
          altsvc_scratch_.host_len > current_frame_length_) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
        return 0;
      }
      altsvc_scratch_.host.reset(new char[altsvc_scratch_.host_len]);
      // Once we have host length, we can also determine the origin length
      // by process of elimination.
      altsvc_scratch_.origin_len = current_frame_length_ -
        GetAltSvcMinimumSize() -
        altsvc_scratch_.pid_len -
        altsvc_scratch_.host_len;
      if (altsvc_scratch_.origin_len > 0) {
        altsvc_scratch_.origin.reset(new char[altsvc_scratch_.origin_len]);
      }
      data += processing;
      processed_bytes += processing;
      len -= processing;
      continue;
    } else if (altsvc_scratch_.host_buf_len < altsvc_scratch_.host_len) {
      // Buffer host field as it comes in.
      // TODO(mlavan): check formatting for host and origin
      buffer = altsvc_scratch_.host.get();
      buffer_len = &altsvc_scratch_.host_buf_len;
      bytes_remaining = altsvc_scratch_.host_len - altsvc_scratch_.host_buf_len;
    } else {
      // Buffer (optional) origin field as it comes in.
      if (altsvc_scratch_.origin_len <= 0) {
        set_error(SPDY_INVALID_CONTROL_FRAME);
        return 0;
      }
      buffer = altsvc_scratch_.origin.get();
      buffer_len = &altsvc_scratch_.origin_buf_len;
      bytes_remaining = remaining_data_length_ -
        processed_bytes -
        altsvc_scratch_.origin_buf_len;
      if (len > bytes_remaining) {
        // This is our last field; there shouldn't be any more bytes.
        set_error(SPDY_INVALID_CONTROL_FRAME);
        return 0;
      }
    }

    // Copy data bytes into the appropriate field.
    processing = std::min(len, bytes_remaining);
    memcpy(buffer + *buffer_len,
           data,
           processing);
    *buffer_len += processing;
    data += processing;
    processed_bytes += processing;
    len -= processing;
  }

  remaining_data_length_ -= processed_bytes;
  if (remaining_data_length_ == 0) {
    visitor_->OnAltSvc(current_frame_stream_id_,
                       altsvc_scratch_.max_age,
                       altsvc_scratch_.port,
                       StringPiece(altsvc_scratch_.protocol_id.get(),
                                   altsvc_scratch_.pid_len),
                       StringPiece(altsvc_scratch_.host.get(),
                                   altsvc_scratch_.host_len),
                       StringPiece(altsvc_scratch_.origin.get(),
                                   altsvc_scratch_.origin_len));
    CHANGE_STATE(SPDY_AUTO_RESET);
  }

  return processed_bytes;
}

size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
  DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);

  size_t original_len = len;
  if (remaining_padding_length_fields_ == 0) {
    DCHECK_EQ(remaining_padding_payload_length_, 0u);
    bool pad_low = false;
    bool pad_high = false;
    if (current_frame_flags_ & DATA_FLAG_PAD_LOW) {
      pad_low = true;
      ++remaining_padding_length_fields_;
    }
    if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) {
      pad_high = true;
      ++remaining_padding_length_fields_;
    }
    if ((pad_high && !pad_low) ||
        remaining_data_length_ < remaining_padding_length_fields_) {
      set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
      return 0;
    }
  }

  // Parse the padding length.
  while (len != 0 && remaining_padding_length_fields_ != 0) {
    remaining_padding_payload_length_ =
        (remaining_padding_payload_length_ << 8) +
        *reinterpret_cast<const uint8*>(data);
    ++data;
    --len;
    --remaining_padding_length_fields_;
    --remaining_data_length_;
  }

  if (remaining_padding_length_fields_ == 0) {
    if (remaining_padding_payload_length_ > remaining_data_length_) {
      set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
      return 0;
    }
    if (current_frame_type_ == DATA) {
      CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
    } else {
      DCHECK(current_frame_type_ == HEADERS ||
             current_frame_type_ == PUSH_PROMISE ||
             current_frame_type_ == CONTINUATION ||
             current_frame_type_ == SYN_STREAM ||
             current_frame_type_ == SYN_REPLY)
          << current_frame_type_;
      CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
    }
  }
  return original_len - len;
}

size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
  DCHECK_EQ(SPDY_CONSUME_PADDING, state_);

  size_t original_len = len;
  if (remaining_padding_payload_length_ > 0) {
    DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
    size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
    if (current_frame_type_ == DATA && amount_to_discard > 0) {
      // The visitor needs to know about padding so it can send window updates.
      // Communicate the padding to the visitor through a NULL data pointer,
      // with a nonzero size.
      visitor_->OnStreamFrameData(
          current_frame_stream_id_, NULL, amount_to_discard, false);
    }
    data += amount_to_discard;
    len -= amount_to_discard;
    remaining_padding_payload_length_ -= amount_to_discard;
    remaining_data_length_ -= amount_to_discard;
  }

  if (remaining_data_length_ == 0) {
    // If the FIN flag is set, or this ends a header block which set FIN,
    // inform the visitor of EOF via a 0-length data frame.
    if (expect_continuation_ == 0 &&
        ((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 ||
         end_stream_when_done_)) {
      end_stream_when_done_ = false;
      visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
    }
    CHANGE_STATE(SPDY_AUTO_RESET);
  }
  return original_len - len;
}

size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
  size_t original_len = len;
  if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
    size_t amount_to_forward = std::min(
        remaining_data_length_ - remaining_padding_payload_length_, 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_frame_stream_id_, data, amount_to_forward, false);
      }
    }
    data += amount_to_forward;
    len -= amount_to_forward;
    remaining_data_length_ -= amount_to_forward;
  }

  if (remaining_data_length_ == remaining_padding_payload_length_) {
    CHANGE_STATE(SPDY_CONSUME_PADDING);
  }
  return original_len - len;
}

size_t SpdyFramer::ProcessIgnoredControlFramePayload(/*const char* data,*/
                                                     size_t len) {
  size_t original_len = len;
  if (remaining_data_length_ > 0) {
    size_t amount_to_ignore = std::min(remaining_data_length_, len);
    len -= amount_to_ignore;
    remaining_data_length_ -= amount_to_ignore;
  }

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

size_t 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 (protocol_version() <= SPDY2) {
    uint16 temp;
    if (!reader.ReadUInt16(&temp)) {
      DVLOG(1) << "Unable to read number of headers.";
      return 0;
    }
    num_headers = temp;
  } else {
    if (!reader.ReadUInt32(&num_headers)) {
      DVLOG(1) << "Unable to read number of headers.";
      return 0;
    }
  }

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

    // Read header name.
    if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
                            : !reader.ReadStringPiece32(&temp)) {
      DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
               << num_headers << ").";
      return 0;
    }
    std::string name = temp.as_string();

    // Read header value.
    if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
                            : !reader.ReadStringPiece32(&temp)) {
      DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
               << num_headers << ").";
      return 0;
    }
    std::string value = temp.as_string();

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

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

SpdySerializedFrame* SpdyFramer::SerializeData(
    const SpdyDataIR& data_ir) const {
  uint8 flags = DATA_FLAG_NONE;
  if (data_ir.fin()) {
    flags = DATA_FLAG_FIN;
  }

  if (protocol_version() > SPDY3) {
    int num_padding_fields = 0;
    if (data_ir.pad_low()) {
      flags |= DATA_FLAG_PAD_LOW;
      ++num_padding_fields;
    }
    if (data_ir.pad_high()) {
      flags |= DATA_FLAG_PAD_HIGH;
      ++num_padding_fields;
    }

    const size_t size_with_padding = num_padding_fields +
        data_ir.data().length() + data_ir.padding_payload_len() +
        GetDataFrameMinimumSize();
    SpdyFrameBuilder builder(size_with_padding, protocol_version());
    builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
    if (data_ir.pad_high()) {
      builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
    }
    if (data_ir.pad_low()) {
      builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
    }
    builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
    if (data_ir.padding_payload_len() > 0) {
      string padding = string(data_ir.padding_payload_len(), '0');
      builder.WriteBytes(padding.data(), padding.length());
    }
    DCHECK_EQ(size_with_padding, builder.length());
    return builder.take();
  } else {
    const size_t size = GetDataFrameMinimumSize() + data_ir.data().length();
    SpdyFrameBuilder builder(size, protocol_version());
    builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
    builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
    DCHECK_EQ(size, builder.length());
    return builder.take();
  }
}

SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
    const SpdyDataIR& data_ir) const {
  uint8 flags = DATA_FLAG_NONE;
  if (data_ir.fin()) {
    flags = DATA_FLAG_FIN;
  }

  size_t frame_size = GetDataFrameMinimumSize();
  size_t num_padding_fields = 0;
  if (protocol_version() > SPDY3) {
    if (data_ir.pad_low()) {
      flags |= DATA_FLAG_PAD_LOW;
      ++num_padding_fields;
    }
    if (data_ir.pad_high()) {
      flags |= DATA_FLAG_PAD_HIGH;
      ++num_padding_fields;
    }
    frame_size += num_padding_fields;
  }

  SpdyFrameBuilder builder(frame_size, protocol_version());
  builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
  if (protocol_version() > SPDY3) {
    if (data_ir.pad_high()) {
      builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
    }
    if (data_ir.pad_low()) {
      builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
    }
    builder.OverwriteLength(*this,  num_padding_fields +
        data_ir.data().length() + data_ir.padding_payload_len());
  } else {
    builder.OverwriteLength(*this, data_ir.data().length());
  }
  DCHECK_EQ(frame_size, builder.length());
  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeSynStream(
    const SpdySynStreamIR& syn_stream) {
  uint8 flags = 0;
  if (syn_stream.fin()) {
    flags |= CONTROL_FLAG_FIN;
  }
  if (syn_stream.unidirectional()) {
    // TODO(hkhalil): invalid for HTTP2.
    flags |= CONTROL_FLAG_UNIDIRECTIONAL;
  }
  // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now
  // we never expect to have to overflow into a CONTINUATION frame.
  if (protocol_version() > SPDY3) {
    flags |= HEADERS_FLAG_PRIORITY;
    flags |= HEADERS_FLAG_END_HEADERS;
  }

  // Sanitize priority.
  uint8 priority = syn_stream.priority();
  if (priority > GetLowestPriority()) {
    DLOG(DFATAL) << "Priority out-of-bounds.";
    priority = GetLowestPriority();
  }

  // The size of this frame, including variable-length name-value block.
  size_t size = GetSynStreamMinimumSize();

  string hpack_encoding;
  if (protocol_version() > SPDY3) {
    if (enable_compression_) {
      GetHpackEncoder()->EncodeHeaderSet(
          syn_stream.name_value_block(), &hpack_encoding);
    } else {
      GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
          syn_stream.name_value_block(), &hpack_encoding);
    }
    size += hpack_encoding.size();
  } else {
    size += GetSerializedLength(syn_stream.name_value_block());
  }

  SpdyFrameBuilder builder(size, protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
    builder.WriteUInt32(syn_stream.stream_id());
    builder.WriteUInt32(syn_stream.associated_to_stream_id());
    builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
    builder.WriteUInt8(0);  // Unused byte where credential slot used to be.
  } else {
    builder.BeginNewFrame(*this,
                          HEADERS,
                          flags,
                          syn_stream.stream_id());
    // TODO(jgraettinger): Plumb priorities and stream dependencies.
    builder.WriteUInt32(0);  // Non-exclusive bit and root stream ID.
    builder.WriteUInt8(MapPriorityToWeight(priority));
  }
  DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
  if (protocol_version() > SPDY3) {
    builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
  } else {
    SerializeNameValueBlock(&builder, syn_stream);
  }

  if (debug_visitor_) {
    const size_t payload_len = protocol_version() > SPDY3 ?
        hpack_encoding.size() :
        GetSerializedLength(protocol_version(),
                            &(syn_stream.name_value_block()));
    // SPDY 4 reports this compression as a SYN_STREAM compression.
    debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
                                          SYN_STREAM,
                                          payload_len,
                                          builder.length());
  }

  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeSynReply(
    const SpdySynReplyIR& syn_reply) {
  uint8 flags = 0;
  if (syn_reply.fin()) {
    flags |= CONTROL_FLAG_FIN;
  }
  // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now
  // we never expect to have to overflow into a CONTINUATION frame.
  if (protocol_version() > SPDY3) {
    flags |= HEADERS_FLAG_END_HEADERS;
  }

  // The size of this frame, including variable-length name-value block.
  size_t size = GetSynReplyMinimumSize();

  string hpack_encoding;
  if (protocol_version() > SPDY3) {
    if (enable_compression_) {
      GetHpackEncoder()->EncodeHeaderSet(
          syn_reply.name_value_block(), &hpack_encoding);
    } else {
      GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
          syn_reply.name_value_block(), &hpack_encoding);
    }
    size += hpack_encoding.size();
  } else {
    size += GetSerializedLength(syn_reply.name_value_block());
  }

  SpdyFrameBuilder builder(size, protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
    builder.WriteUInt32(syn_reply.stream_id());
  } else {
    builder.BeginNewFrame(*this,
                          HEADERS,
                          flags,
                          syn_reply.stream_id());
  }
  if (protocol_version() < SPDY3) {
    builder.WriteUInt16(0);  // Unused.
  }
  DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
  if (protocol_version() > SPDY3) {
    builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
  } else {
    SerializeNameValueBlock(&builder, syn_reply);
  }

  if (debug_visitor_) {
    const size_t payload_len = protocol_version() > SPDY3 ?
        hpack_encoding.size() :
        GetSerializedLength(protocol_version(),
                            &(syn_reply.name_value_block()));
    debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
                                          SYN_REPLY,
                                          payload_len,
                                          builder.length());
  }

  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeRstStream(
    const SpdyRstStreamIR& rst_stream) const {
  // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
  // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
  // which doesn't currently include RST_STREAM payloads. GFE flags have been
  // commented but left in place to simplify future patching.
  // Compute the output buffer size, taking opaque data into account.
  uint16 expected_length = GetRstStreamMinimumSize();
  if (protocol_version() > SPDY3) {
    expected_length += rst_stream.description().size();
  }
  SpdyFrameBuilder builder(expected_length, protocol_version());

  // Serialize the RST_STREAM frame.
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
    builder.WriteUInt32(rst_stream.stream_id());
  } else {
    builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
  }

  builder.WriteUInt32(rst_stream.status());

  // In SPDY4 and up, RST_STREAM frames may also specify opaque data.
  if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
    builder.WriteBytes(rst_stream.description().data(),
                       rst_stream.description().size());
  }

  DCHECK_EQ(expected_length, builder.length());
  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeSettings(
    const SpdySettingsIR& settings) const {
  uint8 flags = 0;

  if (protocol_version() <= SPDY3) {
    if (settings.clear_settings()) {
      flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
    }
  } else {
    if (settings.is_ack()) {
      flags |= SETTINGS_FLAG_ACK;
    }
  }
  const SpdySettingsIR::ValueMap* values = &(settings.values());

  size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
  // Size, in bytes, of this SETTINGS frame.
  const size_t size = GetSettingsMinimumSize() +
                      (values->size() * setting_size);
  SpdyFrameBuilder builder(size, protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, SETTINGS, flags);
  } else {
    builder.BeginNewFrame(*this, SETTINGS, flags, 0);
  }

  // If this is an ACK, payload should be empty.
  if (protocol_version() > SPDY3 && settings.is_ack()) {
    return builder.take();
  }

  if (protocol_version() <= SPDY3) {
    builder.WriteUInt32(values->size());
  }
  DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
  for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
       it != values->end();
       ++it) {
    if (protocol_version() <= SPDY3) {
      uint8 setting_flags = 0;
      if (it->second.persist_value) {
        setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
      }
      if (it->second.persisted) {
        setting_flags |= SETTINGS_FLAG_PERSISTED;
      }
      SettingsFlagsAndId flags_and_id(
          setting_flags,
          SpdyConstants::SerializeSettingId(protocol_version(), it->first));
      uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
      builder.WriteBytes(&id_and_flags_wire, 4);
    } else {
      builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(),
                                                           it->first));
    }
    builder.WriteUInt32(it->second.value);
  }
  DCHECK_EQ(size, builder.length());
  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
  SpdyFrameBuilder builder(GetPingSize(), protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, PING, kNoFlags);
    builder.WriteUInt32(static_cast<uint32>(ping.id()));
  } else {
    uint8 flags = 0;
    if (ping.is_ack()) {
      flags |= PING_FLAG_ACK;
    }
    builder.BeginNewFrame(*this, PING, flags, 0);
    builder.WriteUInt64(ping.id());
  }
  DCHECK_EQ(GetPingSize(), builder.length());
  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeGoAway(
    const SpdyGoAwayIR& goaway) const {

  // Compute the output buffer size, take opaque data into account.
  uint16 expected_length = GetGoAwayMinimumSize();
  if (protocol_version() > SPDY3) {
    expected_length += goaway.description().size();
  }
  SpdyFrameBuilder builder(expected_length, protocol_version());

  // Serialize the GOAWAY frame.
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
  } else {
    builder.BeginNewFrame(*this, GOAWAY, 0, 0);
  }

  // GOAWAY frames specify the last good stream id for all SPDY versions.
  builder.WriteUInt32(goaway.last_good_stream_id());

  // In SPDY3 and up, GOAWAY frames also specify the error status code.
  if (protocol_version() >= SPDY3) {
    // TODO(jgraettinger): Merge back to server-side.
    builder.WriteUInt32(SpdyConstants::SerializeGoAwayStatus(protocol_version(),
                                                             goaway.status()));
  }

  // In SPDY4 and up, GOAWAY frames may also specify opaque data.
  if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) {
    builder.WriteBytes(goaway.description().data(),
                       goaway.description().size());
  }

  DCHECK_EQ(expected_length, builder.length());
  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeHeaders(
    const SpdyHeadersIR& headers) {
  uint8 flags = 0;
  if (headers.fin()) {
    flags |= CONTROL_FLAG_FIN;
  }
  if (protocol_version() > SPDY3) {
    // This will get overwritten if we overflow into a CONTINUATION frame.
    flags |= HEADERS_FLAG_END_HEADERS;
    if (headers.has_priority()) {
      flags |= HEADERS_FLAG_PRIORITY;
    }
  }

  // The size of this frame, including variable-length name-value block.
  size_t size = GetHeadersMinimumSize();

  uint32 priority = headers.priority();
  if (headers.has_priority()) {
    if (priority > GetLowestPriority()) {
      DLOG(DFATAL) << "Priority out-of-bounds.";
      priority = GetLowestPriority();
    }
    size += 4;
  }

  string hpack_encoding;
  if (protocol_version() > SPDY3) {
    if (enable_compression_) {
      GetHpackEncoder()->EncodeHeaderSet(
          headers.name_value_block(), &hpack_encoding);
    } else {
      GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
          headers.name_value_block(), &hpack_encoding);
    }
    size += hpack_encoding.size();
    if (size > GetControlFrameBufferMaxSize()) {
      size += GetNumberRequiredContinuationFrames(size) *
              GetContinuationMinimumSize();
      flags &= ~HEADERS_FLAG_END_HEADERS;
    }
  } else {
    size += GetSerializedLength(headers.name_value_block());
  }

  SpdyFrameBuilder builder(size, protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, HEADERS, flags);
    builder.WriteUInt32(headers.stream_id());
  } else {
    builder.BeginNewFrame(*this,
                          HEADERS,
                          flags,
                          headers.stream_id());
    if (headers.has_priority()) {
      // TODO(jgraettinger): Plumb priorities and stream dependencies.
      builder.WriteUInt32(0);  // Non-exclusive bit and root stream ID.
      builder.WriteUInt8(MapPriorityToWeight(priority));
    }
  }
  if (protocol_version() <= SPDY2) {
    builder.WriteUInt16(0);  // Unused.
  }
  DCHECK_EQ(GetHeadersMinimumSize(), builder.length());

  if (protocol_version() > SPDY3) {
    WritePayloadWithContinuation(&builder,
                                 hpack_encoding,
                                 headers.stream_id(),
                                 HEADERS);
  } else {
    SerializeNameValueBlock(&builder, headers);
  }

  if (debug_visitor_) {
    const size_t payload_len = protocol_version() > SPDY3 ?
        hpack_encoding.size() :
        GetSerializedLength(protocol_version(),
                            &(headers.name_value_block()));
    debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
                                          HEADERS,
                                          payload_len,
                                          builder.length());
  }

  return builder.take();
}

SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
    const SpdyWindowUpdateIR& window_update) const {
  SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version());
  if (protocol_version() <= SPDY3) {
    builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
    builder.WriteUInt32(window_update.stream_id());
  } else {
    builder.BeginNewFrame(*this,
                          WINDOW_UPDATE,
                          kNoFlags,
                          window_update.stream_id());
  }
  builder.WriteUInt32(window_update.delta());
  DCHECK_EQ(GetWindowUpdateSize(), builder.length());
  return builder.take();
}

SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
  DCHECK_LT(SPDY3, protocol_version());
  SpdyFrameBuilder builder(GetBlockedSize(), protocol_version());
  builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
  return builder.take();
}

SpdyFrame* SpdyFramer::SerializePushPromise(
    const SpdyPushPromiseIR& push_promise) {
  DCHECK_LT(SPDY3, protocol_version());
  uint8 flags = 0;
  // This will get overwritten if we overflow into a CONTINUATION frame.
  flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
  // The size of this frame, including variable-length name-value block.
  size_t size = GetPushPromiseMinimumSize();

  string hpack_encoding;
  if (protocol_version() > SPDY3) {
    if (enable_compression_) {
      GetHpackEncoder()->EncodeHeaderSet(
          push_promise.name_value_block(), &hpack_encoding);
    } else {
      GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
          push_promise.name_value_block(), &hpack_encoding);
    }
    size += hpack_encoding.size();
    if (size > GetControlFrameBufferMaxSize()) {
      size += GetNumberRequiredContinuationFrames(size) *
              GetContinuationMinimumSize();
      flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
    }
  } else {
    size += GetSerializedLength(push_promise.name_value_block());
  }

  SpdyFrameBuilder builder(size, protocol_version());
  builder.BeginNewFrame(*this,
                        PUSH_PROMISE,
                        flags,
                        push_promise.stream_id());
  builder.WriteUInt32(push_promise.promised_stream_id());
  DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());

  if (protocol_version() > SPDY3) {
    WritePayloadWithContinuation(&builder,
                                 hpack_encoding,
                                 push_promise.stream_id(),
                                 PUSH_PROMISE);
  } else {
    SerializeNameValueBlock(&builder, push_promise);
  }

  if (debug_visitor_) {
    const size_t payload_len = protocol_version() > SPDY3 ?
        hpack_encoding.size() :
        GetSerializedLength(protocol_version(),
                            &(push_promise.name_value_block()));
    debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
        PUSH_PROMISE, payload_len, builder.length());
  }

  return builder.take();
}

// TODO(jgraettinger): This implementation is incorrect. The continuation
// frame continues a previously-begun HPACK encoding; it doesn't begin a
// new one. Figure out whether it makes sense to keep SerializeContinuation().
SpdyFrame* SpdyFramer::SerializeContinuation(
    const SpdyContinuationIR& continuation) {
  CHECK_LT(SPDY3, protocol_version());
  uint8 flags = 0;
  if (continuation.end_headers()) {
    flags |= HEADERS_FLAG_END_HEADERS;
  }

  // The size of this frame, including variable-length name-value block.
  size_t size = GetContinuationMinimumSize();
  string hpack_encoding;
  if (enable_compression_) {
    GetHpackEncoder()->EncodeHeaderSet(
        continuation.name_value_block(), &hpack_encoding);
  } else {
    GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
        continuation.name_value_block(), &hpack_encoding);
  }
  size += hpack_encoding.size();

  SpdyFrameBuilder builder(size, protocol_version());
  builder.BeginNewFrame(*this, CONTINUATION, flags,
      continuation.stream_id());
  DCHECK_EQ(GetContinuationMinimumSize(), builder.length());

  builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());

  if (debug_visitor_) {
    const size_t payload_len = hpack_encoding.size();
    debug_visitor_->OnSendCompressedFrame(continuation.stream_id(),
        CONTINUATION, payload_len, builder.length());
  }

  return builder.take();
}

SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) {
  DCHECK_LT(SPDY3, protocol_version());
  size_t size = GetAltSvcMinimumSize();
  size += altsvc.protocol_id().length();
  size += altsvc.host().length();
  size += altsvc.origin().length();

  SpdyFrameBuilder builder(size, protocol_version());
  builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id());

  builder.WriteUInt32(altsvc.max_age());
  builder.WriteUInt16(altsvc.port());
  builder.WriteUInt8(0);  // Reserved.
  builder.WriteUInt8(altsvc.protocol_id().length());
  builder.WriteBytes(altsvc.protocol_id().data(),
                     altsvc.protocol_id().length());
  builder.WriteUInt8(altsvc.host().length());
  builder.WriteBytes(altsvc.host().data(), altsvc.host().length());
  builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length());
  DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
  return builder.take();
}

namespace {

class FrameSerializationVisitor : public SpdyFrameVisitor {
 public:
  explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
  virtual ~FrameSerializationVisitor() {}

  SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }

  virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
    frame_.reset(framer_->SerializeData(data));
  }
  virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE {
    frame_.reset(framer_->SerializeSynStream(syn_stream));
  }
  virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE {
    frame_.reset(framer_->SerializeSynReply(syn_reply));
  }
  virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE {
    frame_.reset(framer_->SerializeRstStream(rst_stream));
  }
  virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE {
    frame_.reset(framer_->SerializeSettings(settings));
  }
  virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE {
    frame_.reset(framer_->SerializePing(ping));
  }
  virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE {
    frame_.reset(framer_->SerializeGoAway(goaway));
  }
  virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE {
    frame_.reset(framer_->SerializeHeaders(headers));
  }
  virtual void VisitWindowUpdate(
      const SpdyWindowUpdateIR& window_update) OVERRIDE {
    frame_.reset(framer_->SerializeWindowUpdate(window_update));
  }
  virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE {
    frame_.reset(framer_->SerializeBlocked(blocked));
  }
  virtual void VisitPushPromise(
      const SpdyPushPromiseIR& push_promise) OVERRIDE {
    frame_.reset(framer_->SerializePushPromise(push_promise));
  }
  virtual void VisitContinuation(
      const SpdyContinuationIR& continuation) OVERRIDE {
    frame_.reset(framer_->SerializeContinuation(continuation));
  }
  virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE {
    frame_.reset(framer_->SerializeAltSvc(altsvc));
  }

 private:
  SpdyFramer* framer_;
  scoped_ptr<SpdySerializedFrame> frame_;
};

}  // namespace

SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
  FrameSerializationVisitor visitor(this);
  frame.Visit(&visitor);
  return visitor.ReleaseSerializedFrame();
}

size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
  CHECK_GE(SPDY3, protocol_version());
  const size_t uncompressed_length =
    GetSerializedLength(protocol_version(), &headers);
  if (!enable_compression_) {
    return uncompressed_length;
  }
  z_stream* compressor = GetHeaderCompressor();
  // Since we'll be performing lots of flushes when compressing the data,
  // zlib's lower bounds may be insufficient.
  return 2 * deflateBound(compressor, uncompressed_length);
}

size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
  const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
  DCHECK_GT(protocol_version(), SPDY3);
  DCHECK_GT(size, kMaxControlFrameSize);
  size_t overflow = size - kMaxControlFrameSize;
  return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
}

void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
                                              const string& hpack_encoding,
                                              SpdyStreamId stream_id,
                                              SpdyFrameType type) {
  const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();

    // In addition to the prefix, fixed_field_size includes the size of
    // any fields that come before the variable-length name/value block.
    size_t fixed_field_size = 0;
    uint8 end_flag = 0;
    uint8 flags = 0;
    if (type == HEADERS) {
      fixed_field_size = GetHeadersMinimumSize();
      end_flag = HEADERS_FLAG_END_HEADERS;
    } else if (type == PUSH_PROMISE) {
      fixed_field_size = GetPushPromiseMinimumSize();
      end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
    } else {
      DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
                  << FrameTypeToString(type);
    }

    // Write as much of the payload as possible into the initial frame.
    size_t bytes_remaining = hpack_encoding.size() -
        std::min(hpack_encoding.size(),
                 kMaxControlFrameSize - fixed_field_size);
    builder->WriteBytes(&hpack_encoding[0],
                        hpack_encoding.size() - bytes_remaining);

    if (bytes_remaining > 0) {
      builder->OverwriteLength(*this,
          kMaxControlFrameSize - GetControlFrameHeaderSize());
    }

    // Tack on CONTINUATION frames for the overflow.
    while (bytes_remaining > 0) {
      size_t bytes_to_write = std::min(bytes_remaining,
                                       kMaxControlFrameSize -
                                       GetContinuationMinimumSize());
      // Write CONTINUATION frame prefix.
      if (bytes_remaining == bytes_to_write) {
        flags |= end_flag;
      }
      builder->BeginNewFrame(*this,
                             CONTINUATION,
                             flags,
                             stream_id);
      // Write payload fragment.
      builder->WriteBytes(&hpack_encoding[hpack_encoding.size() -
                                          bytes_remaining],
                          bytes_to_write);
      bytes_remaining -= bytes_to_write;
    }
}

// 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 = (protocol_version() <= SPDY2) ?
        kV2Dictionary : kV3Dictionary;
    const int dictionary_size = (protocol_version() <= SPDY2) ?
        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();
}

HpackEncoder* SpdyFramer::GetHpackEncoder() {
  DCHECK_LT(SPDY3, spdy_version_);
  if (hpack_encoder_.get() == NULL) {
    hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
  }
  return hpack_encoder_.get();
}

HpackDecoder* SpdyFramer::GetHpackDecoder() {
  DCHECK_LT(SPDY3, spdy_version_);
  if (hpack_decoder_.get() == NULL) {
    hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
  }
  return hpack_decoder_.get();
}

uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
  const float kSteps = 255.9f / 7.f;
  return static_cast<uint8>(kSteps * (7.f - priority));
}

SpdyPriority SpdyFramer::MapWeightToPriority(uint8 weight) {
  const float kSteps = 255.9f / 7.f;
  return static_cast<SpdyPriority>(7.f - weight / kSteps);
}

// 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(
    SpdyStreamId stream_id,
    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;
  // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we
  // signal an error back in ProcessControlFrameBeforeHeaderBlock.  So if we've
  // reached this method successfully, stream_id should be nonzero.
  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 = (protocol_version() <= SPDY2) ? kV2Dictionary
                                                             : kV3Dictionary;
      const int dictionary_size = (protocol_version() <= SPDY2) ?
          kV2DictionarySize : kV3DictionarySize;
      const DictionaryIds& ids = g_dictionary_ids.Get();
      const uLong dictionary_id = (protocol_version() <= SPDY2) ?
          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(
    SpdyStreamId stream_id, const char* data, size_t len) {
  bool read_successfully = true;
  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;
}

void SpdyFramer::SerializeNameValueBlockWithoutCompression(
    SpdyFrameBuilder* builder,
    const SpdyNameValueBlock& name_value_block) const {
  // Serialize number of headers.
  if (protocol_version() <= SPDY2) {
    builder->WriteUInt16(name_value_block.size());
  } else {
    builder->WriteUInt32(name_value_block.size());
  }

  // Serialize each header.
  for (SpdyHeaderBlock::const_iterator it = name_value_block.begin();
       it != name_value_block.end();
       ++it) {
    if (protocol_version() <= SPDY2) {
      builder->WriteString(it->first);
      builder->WriteString(it->second);
    } else {
      builder->WriteStringPiece32(it->first);
      builder->WriteStringPiece32(it->second);
    }
  }
}

void SpdyFramer::SerializeNameValueBlock(
    SpdyFrameBuilder* builder,
    const SpdyFrameWithNameValueBlockIR& frame) {
  CHECK_GE(SPDY3, protocol_version());
  if (!enable_compression_) {
    return SerializeNameValueBlockWithoutCompression(builder,
                                                     frame.name_value_block());
  }

  // First build an uncompressed version to be fed into the compressor.
  const size_t uncompressed_len = GetSerializedLength(
      protocol_version(), &(frame.name_value_block()));
  SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version());
  SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
                                            frame.name_value_block());
  scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());

  z_stream* compressor = GetHeaderCompressor();
  if (!compressor) {
    LOG(DFATAL) << "Could not obtain compressor.";
    return;
  }

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

  // Create an output frame.
  // Since we'll be performing lots of flushes when compressing the data,
  // zlib's lower bounds may be insufficient.
  //
  // TODO(akalin): Avoid the duplicate calculation with
  // GetSerializedLength(const SpdyHeaderBlock&).
  const int compressed_max_size =
      2 * deflateBound(compressor, uncompressed_len);

  // 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*>(uncompressed_payload->data());
  compressor->avail_in = uncompressed_len;
#endif  // defined(USE_SYSTEM_ZLIB)
  compressor->next_out = reinterpret_cast<Bytef*>(
      builder->GetWritableBuffer(compressed_max_size));
  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;
    // TODO(akalin): Upstream this return.
    return;
  }
#else
  WriteHeaderBlockToZ(&frame.name_value_block(), compressor);
#endif  // defined(USE_SYSTEM_ZLIB)

  int compressed_size = compressed_max_size - compressor->avail_out;
  builder->Seek(compressed_size);
  builder->RewriteLength(*this);

  pre_compress_bytes.Add(uncompressed_len);
  post_compress_bytes.Add(compressed_size);

  compressed_frames.Increment();
}

}  // namespace net
