Home | History | Annotate | Download | only in spdy
      1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/spdy/spdy_framer.h"
      6 
      7 #include "base/lazy_instance.h"
      8 #include "base/memory/scoped_ptr.h"
      9 #include "base/metrics/stats_counters.h"
     10 #include "base/third_party/valgrind/memcheck.h"
     11 #include "net/spdy/spdy_frame_builder.h"
     12 #include "net/spdy/spdy_frame_reader.h"
     13 #include "net/spdy/spdy_bitmasks.h"
     14 #include "third_party/zlib/zlib.h"
     15 
     16 using base::StringPiece;
     17 using std::string;
     18 using std::vector;
     19 
     20 namespace net {
     21 
     22 namespace {
     23 
     24 // Compute the id of our dictionary so that we know we're using the
     25 // right one when asked for it.
     26 uLong CalculateDictionaryId(const char* dictionary,
     27                             const size_t dictionary_size) {
     28   uLong initial_value = adler32(0L, Z_NULL, 0);
     29   return adler32(initial_value,
     30                  reinterpret_cast<const Bytef*>(dictionary),
     31                  dictionary_size);
     32 }
     33 
     34 // Check to see if the name and value of a cookie are both empty.
     35 bool IsCookieEmpty(const base::StringPiece& cookie) {
     36   if (cookie.size() == 0) {
     37      return true;
     38   }
     39   size_t pos = cookie.find('=');
     40   if (pos  == base::StringPiece::npos) {
     41      return false;
     42   }
     43   // Ignore leading whitespaces of cookie value.
     44   size_t value_start = pos + 1;
     45   for (; value_start < cookie.size(); value_start++) {
     46      if (!(cookie[value_start] == ' ' || cookie[value_start] == '\t')) {
     47         break;
     48      }
     49   }
     50   return (pos == 0) && ((cookie.size() - value_start) == 0);
     51 }
     52 
     53 struct DictionaryIds {
     54   DictionaryIds()
     55     : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
     56       v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
     57   {}
     58   const uLong v2_dictionary_id;
     59   const uLong v3_dictionary_id;
     60 };
     61 
     62 // Adler ID for the SPDY header compressor dictionaries. Note that they are
     63 // initialized lazily to avoid static initializers.
     64 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
     65 
     66 // Used to indicate no flags in a SPDY flags field.
     67 const uint8 kNoFlags = 0;
     68 
     69 // Wire sizes of priority payloads.
     70 const size_t kPriorityDependencyPayloadSize = 4;
     71 const size_t kPriorityWeightPayloadSize = 1;
     72 
     73 }  // namespace
     74 
     75 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1);
     76 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
     77 // The size of the control frame buffer. Must be >= the minimum size of the
     78 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
     79 // calculation details.
     80 const size_t SpdyFramer::kControlFrameBufferSize = 19;
     81 
     82 #ifdef DEBUG_SPDY_STATE_CHANGES
     83 #define CHANGE_STATE(newstate)                                  \
     84   do {                                                          \
     85     DVLOG(1) << "Changing state from: "                         \
     86              << StateToString(state_)                           \
     87              << " to " << StateToString(newstate) << "\n";      \
     88     DCHECK(state_ != SPDY_ERROR);                               \
     89     DCHECK_EQ(previous_state_, state_);                         \
     90     previous_state_ = state_;                                   \
     91     state_ = newstate;                                          \
     92   } while (false)
     93 #else
     94 #define CHANGE_STATE(newstate)                                  \
     95   do {                                                          \
     96     DCHECK(state_ != SPDY_ERROR);                               \
     97     DCHECK_EQ(previous_state_, state_);                         \
     98     previous_state_ = state_;                                   \
     99     state_ = newstate;                                          \
    100   } while (false)
    101 #endif
    102 
    103 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(
    104     SpdyMajorVersion version, uint32 wire) {
    105   if (version < SPDY3) {
    106     ConvertFlagsAndIdForSpdy2(&wire);
    107   }
    108   return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
    109 }
    110 
    111 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
    112     : flags_(flags), id_(id & 0x00ffffff) {
    113   LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id;
    114 }
    115 
    116 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
    117     const {
    118   uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
    119   if (version < SPDY3) {
    120     ConvertFlagsAndIdForSpdy2(&wire);
    121   }
    122   return wire;
    123 }
    124 
    125 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
    126 // This method is used to preserve buggy behavior and works on both
    127 // little-endian and big-endian hosts.
    128 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
    129 // as well as vice versa).
    130 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
    131     uint8* wire_array = reinterpret_cast<uint8*>(val);
    132     std::swap(wire_array[0], wire_array[3]);
    133     std::swap(wire_array[1], wire_array[2]);
    134 }
    135 
    136 SpdyAltSvcScratch::SpdyAltSvcScratch() { Reset(); }
    137 SpdyAltSvcScratch::~SpdyAltSvcScratch() {}
    138 
    139 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
    140                                                    size_t len) {
    141   return true;
    142 }
    143 
    144 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
    145     const char* rst_stream_data,
    146     size_t len) {
    147   return true;
    148 }
    149 
    150 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
    151     : current_frame_buffer_(new char[kControlFrameBufferSize]),
    152       enable_compression_(true),
    153       visitor_(NULL),
    154       debug_visitor_(NULL),
    155       display_protocol_("SPDY"),
    156       spdy_version_(version),
    157       syn_frame_processed_(false),
    158       probable_http_response_(false),
    159       expect_continuation_(0),
    160       end_stream_when_done_(false) {
    161   DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
    162   DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
    163   Reset();
    164 }
    165 
    166 SpdyFramer::~SpdyFramer() {
    167   if (header_compressor_.get()) {
    168     deflateEnd(header_compressor_.get());
    169   }
    170   if (header_decompressor_.get()) {
    171     inflateEnd(header_decompressor_.get());
    172   }
    173 }
    174 
    175 void SpdyFramer::Reset() {
    176   state_ = SPDY_RESET;
    177   previous_state_ = SPDY_RESET;
    178   error_code_ = SPDY_NO_ERROR;
    179   remaining_data_length_ = 0;
    180   remaining_control_header_ = 0;
    181   current_frame_buffer_length_ = 0;
    182   current_frame_type_ = DATA;
    183   current_frame_flags_ = 0;
    184   current_frame_length_ = 0;
    185   current_frame_stream_id_ = kInvalidStream;
    186   settings_scratch_.Reset();
    187   altsvc_scratch_.Reset();
    188   remaining_padding_payload_length_ = 0;
    189 }
    190 
    191 size_t SpdyFramer::GetDataFrameMinimumSize() const {
    192   return SpdyConstants::GetDataFrameMinimumSize(protocol_version());
    193 }
    194 
    195 // Size, in bytes, of the control frame header.
    196 size_t SpdyFramer::GetControlFrameHeaderSize() const {
    197   return SpdyConstants::GetControlFrameHeaderSize(protocol_version());
    198 }
    199 
    200 size_t SpdyFramer::GetSynStreamMinimumSize() const {
    201   // Size, in bytes, of a SYN_STREAM frame not including the variable-length
    202   // name-value block.
    203   if (protocol_version() <= SPDY3) {
    204     // Calculated as:
    205     // control frame header + 2 * 4 (stream IDs) + 1 (priority)
    206     // + 1 (unused, was credential slot)
    207     return GetControlFrameHeaderSize() + 10;
    208   } else {
    209     return GetControlFrameHeaderSize() +
    210         kPriorityDependencyPayloadSize +
    211         kPriorityWeightPayloadSize;
    212   }
    213 }
    214 
    215 size_t SpdyFramer::GetSynReplyMinimumSize() const {
    216   // Size, in bytes, of a SYN_REPLY frame not including the variable-length
    217   // name-value block.
    218   size_t size = GetControlFrameHeaderSize();
    219   if (protocol_version() <= SPDY3) {
    220     // Calculated as:
    221     // control frame header + 4 (stream IDs)
    222     size += 4;
    223   }
    224 
    225   // In SPDY 2, there were 2 unused bytes before payload.
    226   if (protocol_version() < SPDY3) {
    227     size += 2;
    228   }
    229 
    230   return size;
    231 }
    232 
    233 size_t SpdyFramer::GetRstStreamMinimumSize() const {
    234   // Size, in bytes, of a RST_STREAM frame.
    235   if (protocol_version() <= SPDY3) {
    236     // Calculated as:
    237     // control frame header + 4 (stream id) + 4 (status code)
    238     return GetControlFrameHeaderSize() + 8;
    239   } else {
    240     // Calculated as:
    241     // frame prefix + 4 (status code)
    242     return GetControlFrameHeaderSize() + 4;
    243   }
    244 }
    245 
    246 size_t SpdyFramer::GetSettingsMinimumSize() const {
    247   // Size, in bytes, of a SETTINGS frame not including the IDs and values
    248   // from the variable-length value block. Calculated as:
    249   // control frame header + 4 (number of ID/value pairs)
    250   if (protocol_version() <= SPDY3) {
    251     return GetControlFrameHeaderSize() + 4;
    252   } else {
    253     return GetControlFrameHeaderSize();
    254   }
    255 }
    256 
    257 size_t SpdyFramer::GetPingSize() const {
    258   // Size, in bytes, of this PING frame.
    259   if (protocol_version() <= SPDY3) {
    260     // Calculated as:
    261     // control frame header + 4 (id)
    262     return GetControlFrameHeaderSize() + 4;
    263   } else {
    264     // Calculated as:
    265     // control frame header + 8 (id)
    266     return GetControlFrameHeaderSize() + 8;
    267   }
    268 }
    269 
    270 size_t SpdyFramer::GetGoAwayMinimumSize() const {
    271   // Size, in bytes, of this GOAWAY frame. Calculated as:
    272   // 1. Control frame header size
    273   size_t size = GetControlFrameHeaderSize();
    274 
    275   // 2. Last good stream id (4 bytes)
    276   size += 4;
    277 
    278   // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
    279   if (protocol_version() >= SPDY3) {
    280     size += 4;
    281   }
    282 
    283   return size;
    284 }
    285 
    286 size_t SpdyFramer::GetHeadersMinimumSize() const  {
    287   // Size, in bytes, of a HEADERS frame not including the variable-length
    288   // name-value block.
    289   size_t size = GetControlFrameHeaderSize();
    290   if (protocol_version() <= SPDY3) {
    291     // Calculated as:
    292     // control frame header + 4 (stream IDs)
    293     size += 4;
    294   }
    295 
    296   // In SPDY 2, there were 2 unused bytes before payload.
    297   if (protocol_version() <= SPDY2) {
    298     size += 2;
    299   }
    300 
    301   return size;
    302 }
    303 
    304 size_t SpdyFramer::GetWindowUpdateSize() const {
    305   // Size, in bytes, of a WINDOW_UPDATE frame.
    306   if (protocol_version() <= SPDY3) {
    307     // Calculated as:
    308     // control frame header + 4 (stream id) + 4 (delta)
    309     return GetControlFrameHeaderSize() + 8;
    310   } else {
    311     // Calculated as:
    312     // frame prefix + 4 (delta)
    313     return GetControlFrameHeaderSize() + 4;
    314   }
    315 }
    316 
    317 size_t SpdyFramer::GetBlockedSize() const {
    318   DCHECK_LT(SPDY3, protocol_version());
    319   // Size, in bytes, of a BLOCKED frame.
    320   // The BLOCKED frame has no payload beyond the control frame header.
    321   return GetControlFrameHeaderSize();
    322 }
    323 
    324 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
    325   DCHECK_LT(SPDY3, protocol_version());
    326   // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
    327   // Calculated as frame prefix + 4 (promised stream id).
    328   return GetControlFrameHeaderSize() + 4;
    329 }
    330 
    331 size_t SpdyFramer::GetContinuationMinimumSize() const {
    332   // Size, in bytes, of a CONTINUATION frame not including the variable-length
    333   // headers fragments.
    334   return GetControlFrameHeaderSize();
    335 }
    336 
    337 size_t SpdyFramer::GetAltSvcMinimumSize() const {
    338   // Size, in bytes, of an ALTSVC frame not including the Protocol-ID, Host, and
    339   // (optional) Origin fields, all of which can vary in length.
    340   // Note that this gives a lower bound on the frame size rather than a true
    341   // minimum; the actual frame should always be larger than this.
    342   // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte)
    343   // + 1 (pid_len) + 1 (host_len).
    344   return GetControlFrameHeaderSize() + 9;
    345 }
    346 
    347 size_t SpdyFramer::GetPrioritySize() const {
    348   // Size, in bytes, of a PRIORITY frame.
    349   return GetControlFrameHeaderSize() +
    350       kPriorityDependencyPayloadSize +
    351       kPriorityWeightPayloadSize;
    352 }
    353 
    354 size_t SpdyFramer::GetFrameMinimumSize() const {
    355   return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
    356 }
    357 
    358 size_t SpdyFramer::GetFrameMaximumSize() const {
    359   return SpdyConstants::GetFrameMaximumSize(protocol_version());
    360 }
    361 
    362 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
    363   return GetFrameMaximumSize() - GetDataFrameMinimumSize();
    364 }
    365 
    366 size_t SpdyFramer::GetPrefixLength(SpdyFrameType type) const {
    367   return SpdyConstants::GetPrefixLength(type, protocol_version());
    368 }
    369 
    370 const char* SpdyFramer::StateToString(int state) {
    371   switch (state) {
    372     case SPDY_ERROR:
    373       return "ERROR";
    374     case SPDY_AUTO_RESET:
    375       return "AUTO_RESET";
    376     case SPDY_RESET:
    377       return "RESET";
    378     case SPDY_READING_COMMON_HEADER:
    379       return "READING_COMMON_HEADER";
    380     case SPDY_CONTROL_FRAME_PAYLOAD:
    381       return "CONTROL_FRAME_PAYLOAD";
    382     case SPDY_READ_PADDING_LENGTH:
    383       return "SPDY_READ_PADDING_LENGTH";
    384     case SPDY_CONSUME_PADDING:
    385       return "SPDY_CONSUME_PADDING";
    386     case SPDY_IGNORE_REMAINING_PAYLOAD:
    387       return "IGNORE_REMAINING_PAYLOAD";
    388     case SPDY_FORWARD_STREAM_FRAME:
    389       return "FORWARD_STREAM_FRAME";
    390     case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
    391       return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
    392     case SPDY_CONTROL_FRAME_HEADER_BLOCK:
    393       return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
    394     case SPDY_GOAWAY_FRAME_PAYLOAD:
    395       return "SPDY_GOAWAY_FRAME_PAYLOAD";
    396     case SPDY_RST_STREAM_FRAME_PAYLOAD:
    397       return "SPDY_RST_STREAM_FRAME_PAYLOAD";
    398     case SPDY_SETTINGS_FRAME_PAYLOAD:
    399       return "SPDY_SETTINGS_FRAME_PAYLOAD";
    400     case SPDY_ALTSVC_FRAME_PAYLOAD:
    401       return "SPDY_ALTSVC_FRAME_PAYLOAD";
    402   }
    403   return "UNKNOWN_STATE";
    404 }
    405 
    406 void SpdyFramer::set_error(SpdyError error) {
    407   DCHECK(visitor_);
    408   error_code_ = error;
    409   // These values will usually get reset once we come to the end
    410   // of a header block, but if we run into an error that
    411   // might not happen, so reset them here.
    412   expect_continuation_ = 0;
    413   end_stream_when_done_ = false;
    414 
    415   CHANGE_STATE(SPDY_ERROR);
    416   visitor_->OnError(this);
    417 }
    418 
    419 const char* SpdyFramer::ErrorCodeToString(int error_code) {
    420   switch (error_code) {
    421     case SPDY_NO_ERROR:
    422       return "NO_ERROR";
    423     case SPDY_INVALID_CONTROL_FRAME:
    424       return "INVALID_CONTROL_FRAME";
    425     case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
    426       return "CONTROL_PAYLOAD_TOO_LARGE";
    427     case SPDY_ZLIB_INIT_FAILURE:
    428       return "ZLIB_INIT_FAILURE";
    429     case SPDY_UNSUPPORTED_VERSION:
    430       return "UNSUPPORTED_VERSION";
    431     case SPDY_DECOMPRESS_FAILURE:
    432       return "DECOMPRESS_FAILURE";
    433     case SPDY_COMPRESS_FAILURE:
    434       return "COMPRESS_FAILURE";
    435     case SPDY_INVALID_DATA_FRAME_FLAGS:
    436       return "SPDY_INVALID_DATA_FRAME_FLAGS";
    437     case SPDY_INVALID_CONTROL_FRAME_FLAGS:
    438       return "SPDY_INVALID_CONTROL_FRAME_FLAGS";
    439     case SPDY_UNEXPECTED_FRAME:
    440       return "UNEXPECTED_FRAME";
    441   }
    442   return "UNKNOWN_ERROR";
    443 }
    444 
    445 const char* SpdyFramer::StatusCodeToString(int status_code) {
    446   switch (status_code) {
    447     case RST_STREAM_INVALID:
    448       return "INVALID";
    449     case RST_STREAM_PROTOCOL_ERROR:
    450       return "PROTOCOL_ERROR";
    451     case RST_STREAM_INVALID_STREAM:
    452       return "INVALID_STREAM";
    453     case RST_STREAM_REFUSED_STREAM:
    454       return "REFUSED_STREAM";
    455     case RST_STREAM_UNSUPPORTED_VERSION:
    456       return "UNSUPPORTED_VERSION";
    457     case RST_STREAM_CANCEL:
    458       return "CANCEL";
    459     case RST_STREAM_INTERNAL_ERROR:
    460       return "INTERNAL_ERROR";
    461     case RST_STREAM_FLOW_CONTROL_ERROR:
    462       return "FLOW_CONTROL_ERROR";
    463     case RST_STREAM_STREAM_IN_USE:
    464       return "STREAM_IN_USE";
    465     case RST_STREAM_STREAM_ALREADY_CLOSED:
    466       return "STREAM_ALREADY_CLOSED";
    467     case RST_STREAM_INVALID_CREDENTIALS:
    468       return "INVALID_CREDENTIALS";
    469     case RST_STREAM_FRAME_TOO_LARGE:
    470       return "FRAME_TOO_LARGE";
    471     case RST_STREAM_CONNECT_ERROR:
    472       return "CONNECT_ERROR";
    473     case RST_STREAM_ENHANCE_YOUR_CALM:
    474       return "ENHANCE_YOUR_CALM";
    475   }
    476   return "UNKNOWN_STATUS";
    477 }
    478 
    479 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
    480   switch (type) {
    481     case DATA:
    482       return "DATA";
    483     case SYN_STREAM:
    484       return "SYN_STREAM";
    485     case SYN_REPLY:
    486       return "SYN_REPLY";
    487     case RST_STREAM:
    488       return "RST_STREAM";
    489     case SETTINGS:
    490       return "SETTINGS";
    491     case PING:
    492       return "PING";
    493     case GOAWAY:
    494       return "GOAWAY";
    495     case HEADERS:
    496       return "HEADERS";
    497     case WINDOW_UPDATE:
    498       return "WINDOW_UPDATE";
    499     case CREDENTIAL:
    500       return "CREDENTIAL";
    501     case PUSH_PROMISE:
    502       return "PUSH_PROMISE";
    503     case CONTINUATION:
    504       return "CONTINUATION";
    505     case PRIORITY:
    506       return "PRIORITY";
    507     case ALTSVC:
    508       return "ALTSVC";
    509     case BLOCKED:
    510       return "BLOCKED";
    511   }
    512   return "UNKNOWN_CONTROL_TYPE";
    513 }
    514 
    515 size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
    516   DCHECK(visitor_);
    517   DCHECK(data);
    518 
    519   size_t original_len = len;
    520   do {
    521     previous_state_ = state_;
    522     switch (state_) {
    523       case SPDY_ERROR:
    524         goto bottom;
    525 
    526       case SPDY_AUTO_RESET:
    527       case SPDY_RESET:
    528         Reset();
    529         if (len > 0) {
    530           CHANGE_STATE(SPDY_READING_COMMON_HEADER);
    531         }
    532         break;
    533 
    534       case SPDY_READING_COMMON_HEADER: {
    535         size_t bytes_read = ProcessCommonHeader(data, len);
    536         len -= bytes_read;
    537         data += bytes_read;
    538         break;
    539       }
    540 
    541       case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
    542         // Control frames that contain header blocks
    543         // (SYN_STREAM, SYN_REPLY, HEADERS, PUSH_PROMISE, CONTINUATION)
    544         // take a different path through the state machine - they
    545         // will go:
    546         //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
    547         //   2. SPDY_CONTROL_FRAME_HEADER_BLOCK
    548         //
    549         // SETTINGS frames take a slightly modified route:
    550         //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
    551         //   2. SPDY_SETTINGS_FRAME_PAYLOAD
    552         //
    553         //  All other control frames will use the alternate route directly to
    554         //  SPDY_CONTROL_FRAME_PAYLOAD
    555         int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
    556         len -= bytes_read;
    557         data += bytes_read;
    558         break;
    559       }
    560 
    561       case SPDY_SETTINGS_FRAME_PAYLOAD: {
    562         int bytes_read = ProcessSettingsFramePayload(data, len);
    563         len -= bytes_read;
    564         data += bytes_read;
    565         break;
    566       }
    567 
    568       case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
    569         int bytes_read = ProcessControlFrameHeaderBlock(
    570             data, len, protocol_version() > SPDY3);
    571         len -= bytes_read;
    572         data += bytes_read;
    573         break;
    574       }
    575 
    576       case SPDY_RST_STREAM_FRAME_PAYLOAD: {
    577         size_t bytes_read = ProcessRstStreamFramePayload(data, len);
    578         len -= bytes_read;
    579         data += bytes_read;
    580         break;
    581       }
    582 
    583       case SPDY_GOAWAY_FRAME_PAYLOAD: {
    584         size_t bytes_read = ProcessGoAwayFramePayload(data, len);
    585         len -= bytes_read;
    586         data += bytes_read;
    587         break;
    588       }
    589 
    590       case SPDY_ALTSVC_FRAME_PAYLOAD: {
    591         size_t bytes_read = ProcessAltSvcFramePayload(data, len);
    592         len -= bytes_read;
    593         data += bytes_read;
    594         break;
    595       }
    596 
    597       case SPDY_CONTROL_FRAME_PAYLOAD: {
    598         size_t bytes_read = ProcessControlFramePayload(data, len);
    599         len -= bytes_read;
    600         data += bytes_read;
    601         break;
    602       }
    603 
    604       case SPDY_READ_PADDING_LENGTH: {
    605         size_t bytes_read = ProcessFramePaddingLength(data, len);
    606         len -= bytes_read;
    607         data += bytes_read;
    608         break;
    609       }
    610 
    611       case SPDY_CONSUME_PADDING: {
    612         size_t bytes_read = ProcessFramePadding(data, len);
    613         len -= bytes_read;
    614         data += bytes_read;
    615         break;
    616       }
    617 
    618       case SPDY_IGNORE_REMAINING_PAYLOAD: {
    619         size_t bytes_read = ProcessIgnoredControlFramePayload(/*data,*/ len);
    620         len -= bytes_read;
    621         data += bytes_read;
    622         break;
    623       }
    624 
    625       case SPDY_FORWARD_STREAM_FRAME: {
    626         size_t bytes_read = ProcessDataFramePayload(data, len);
    627         len -= bytes_read;
    628         data += bytes_read;
    629         break;
    630       }
    631 
    632       default:
    633         LOG(DFATAL) << "Invalid value for " << display_protocol_
    634                     << " framer state: " << state_;
    635         // This ensures that we don't infinite-loop if state_ gets an
    636         // invalid value somehow, such as due to a SpdyFramer getting deleted
    637         // from a callback it calls.
    638         goto bottom;
    639     }
    640   } while (state_ != previous_state_);
    641  bottom:
    642   DCHECK(len == 0 || state_ == SPDY_ERROR);
    643   if (current_frame_buffer_length_ == 0 &&
    644       remaining_data_length_ == 0 &&
    645       remaining_control_header_ == 0) {
    646     DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
    647         << "State: " << StateToString(state_);
    648   }
    649 
    650   return original_len - len;
    651 }
    652 
    653 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
    654   // This should only be called when we're in the SPDY_READING_COMMON_HEADER
    655   // state.
    656   DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
    657 
    658   size_t original_len = len;
    659 
    660   // Update current frame buffer as needed.
    661   if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
    662     size_t bytes_desired =
    663         GetControlFrameHeaderSize() - current_frame_buffer_length_;
    664     UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
    665   }
    666 
    667   if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
    668     // Not enough information to do anything meaningful.
    669     return original_len - len;
    670   }
    671 
    672   // Using a scoped_ptr here since we may need to create a new SpdyFrameReader
    673   // when processing DATA frames below.
    674   scoped_ptr<SpdyFrameReader> reader(
    675       new SpdyFrameReader(current_frame_buffer_.get(),
    676                           current_frame_buffer_length_));
    677 
    678   uint16 version = 0;
    679   bool is_control_frame = false;
    680 
    681   uint16 control_frame_type_field =
    682     SpdyConstants::DataFrameType(protocol_version());
    683   // ProcessControlFrameHeader() will set current_frame_type_ to the
    684   // correct value if this is a valid control frame.
    685   current_frame_type_ = DATA;
    686   if (protocol_version() <= SPDY3) {
    687     bool successful_read = reader->ReadUInt16(&version);
    688     DCHECK(successful_read);
    689     is_control_frame = (version & kControlFlagMask) != 0;
    690     version &= ~kControlFlagMask;  // Only valid for control frames.
    691     if (is_control_frame) {
    692       // We check version before we check validity: version can never be
    693       // 'invalid', it can only be unsupported.
    694       if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) ||
    695           version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) ||
    696           SpdyConstants::ParseMajorVersion(version) != protocol_version()) {
    697         // Version does not match the version the framer was initialized with.
    698         DVLOG(1) << "Unsupported SPDY version "
    699                  << version
    700                  << " (expected " << protocol_version() << ")";
    701         set_error(SPDY_UNSUPPORTED_VERSION);
    702         return 0;
    703       } else {
    704         // Convert version from wire format to SpdyMajorVersion.
    705         version = SpdyConstants::ParseMajorVersion(version);
    706       }
    707       // We check control_frame_type_field's validity in
    708       // ProcessControlFrameHeader().
    709       successful_read = reader->ReadUInt16(&control_frame_type_field);
    710     } else {
    711       reader->Rewind();
    712       successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    713     }
    714     DCHECK(successful_read);
    715 
    716     successful_read = reader->ReadUInt8(&current_frame_flags_);
    717     DCHECK(successful_read);
    718 
    719     uint32 length_field = 0;
    720     successful_read = reader->ReadUInt24(&length_field);
    721     DCHECK(successful_read);
    722     remaining_data_length_ = length_field;
    723     current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed();
    724   } else {
    725     version = protocol_version();
    726     uint32 length_field = 0;
    727     bool successful_read = reader->ReadUInt24(&length_field);
    728     DCHECK(successful_read);
    729 
    730     uint8 control_frame_type_field_uint8 =
    731       SpdyConstants::DataFrameType(protocol_version());
    732     successful_read = reader->ReadUInt8(&control_frame_type_field_uint8);
    733     DCHECK(successful_read);
    734     // We check control_frame_type_field's validity in
    735     // ProcessControlFrameHeader().
    736     control_frame_type_field = control_frame_type_field_uint8;
    737     is_control_frame = (protocol_version() > SPDY3) ?
    738       control_frame_type_field !=
    739       SpdyConstants::SerializeFrameType(protocol_version(), DATA) :
    740       control_frame_type_field != 0;
    741 
    742     if (is_control_frame) {
    743       current_frame_length_ = length_field + GetControlFrameHeaderSize();
    744     } else {
    745       current_frame_length_ = length_field + GetDataFrameMinimumSize();
    746     }
    747 
    748     successful_read = reader->ReadUInt8(&current_frame_flags_);
    749     DCHECK(successful_read);
    750 
    751     successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    752     DCHECK(successful_read);
    753 
    754     remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed();
    755 
    756     // Before we accept a DATA frame, we need to make sure we're not in the
    757     // middle of processing a header block.
    758     const bool is_continuation_frame = (control_frame_type_field ==
    759         SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION));
    760     if ((expect_continuation_ != 0) != is_continuation_frame) {
    761       if (expect_continuation_ != 0) {
    762         DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION "
    763                     << "frame, but instead received frame type "
    764                     << control_frame_type_field;
    765       } else {
    766         DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame.";
    767       }
    768       set_error(SPDY_UNEXPECTED_FRAME);
    769       return original_len - len;
    770     }
    771   }
    772   DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize()
    773                              : GetDataFrameMinimumSize(),
    774             reader->GetBytesConsumed());
    775   DCHECK_EQ(current_frame_length_,
    776             remaining_data_length_ + reader->GetBytesConsumed());
    777 
    778   // This is just a sanity check for help debugging early frame errors.
    779   if (remaining_data_length_ > 1000000u) {
    780     // The strncmp for 5 is safe because we only hit this point if we
    781     // have kMinCommonHeader (8) bytes
    782     if (!syn_frame_processed_ &&
    783         strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
    784       LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_
    785                    << " request";
    786       probable_http_response_ = true;
    787     } else {
    788       LOG(WARNING) << "Unexpectedly large frame.  " << display_protocol_
    789                    << " session is likely corrupt.";
    790     }
    791   }
    792 
    793   // if we're here, then we have the common header all received.
    794   if (!is_control_frame) {
    795     if (protocol_version() > SPDY3) {
    796       // Catch bogus tests sending oversized DATA frames.
    797       DCHECK_GE(GetFrameMaximumSize(), current_frame_length_)
    798           << "DATA frame too large for SPDY >= 4.";
    799     }
    800 
    801     uint8 valid_data_flags = 0;
    802     if (protocol_version() > SPDY3) {
    803       valid_data_flags =
    804           DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED;
    805     } else {
    806       valid_data_flags = DATA_FLAG_FIN;
    807     }
    808 
    809     if (current_frame_flags_ & ~valid_data_flags) {
    810       set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
    811     } else {
    812       visitor_->OnDataFrameHeader(current_frame_stream_id_,
    813                                   remaining_data_length_,
    814                                   current_frame_flags_ & DATA_FLAG_FIN);
    815       if (remaining_data_length_ > 0) {
    816         CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
    817       } else {
    818         // Empty data frame.
    819         if (current_frame_flags_ & DATA_FLAG_FIN) {
    820           visitor_->OnStreamFrameData(
    821               current_frame_stream_id_, NULL, 0, true);
    822         }
    823         CHANGE_STATE(SPDY_AUTO_RESET);
    824       }
    825     }
    826   } else {
    827     ProcessControlFrameHeader(control_frame_type_field);
    828   }
    829 
    830   return original_len - len;
    831 }
    832 
    833 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
    834   DCHECK_EQ(SPDY_NO_ERROR, error_code_);
    835   DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);
    836 
    837   // TODO(mlavan): Either remove credential frames from the code entirely,
    838   // or add them to parsing + serialization methods for SPDY3.
    839   // Early detection of deprecated frames that we ignore.
    840   if (protocol_version() <= SPDY3) {
    841     if (control_frame_type_field == CREDENTIAL) {
    842       current_frame_type_ = CREDENTIAL;
    843       DCHECK_EQ(SPDY3, protocol_version());
    844       DVLOG(1) << "CREDENTIAL control frame found. Ignoring.";
    845       CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
    846       return;
    847     }
    848   }
    849 
    850   if (!SpdyConstants::IsValidFrameType(protocol_version(),
    851                                        control_frame_type_field)) {
    852     if (protocol_version() <= SPDY3) {
    853       DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field
    854                     << " (protocol version: " << protocol_version() << ")";
    855       set_error(SPDY_INVALID_CONTROL_FRAME);
    856       return;
    857     } else {
    858       // In HTTP2 we ignore unknown frame types for extensibility, as long as
    859       // the rest of the control frame header is valid.
    860       // We rely on the visitor to check validity of current_frame_stream_id_.
    861       bool valid_stream = visitor_->OnUnknownFrame(current_frame_stream_id_,
    862                                                    control_frame_type_field);
    863       if (valid_stream) {
    864         DVLOG(1) << "Ignoring unknown frame type.";
    865         CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
    866       } else {
    867         // Report an invalid frame error and close the stream if the
    868         // stream_id is not valid.
    869         DLOG(WARNING) << "Unknown control frame type "
    870                       << control_frame_type_field
    871                       << " received on invalid stream "
    872                       << current_frame_stream_id_;
    873         set_error(SPDY_INVALID_CONTROL_FRAME);
    874       }
    875       return;
    876     }
    877   }
    878 
    879   current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(),
    880                                                       control_frame_type_field);
    881 
    882   // Do some sanity checking on the control frame sizes and flags.
    883   switch (current_frame_type_) {
    884     case SYN_STREAM:
    885       if (current_frame_length_ < GetSynStreamMinimumSize()) {
    886         set_error(SPDY_INVALID_CONTROL_FRAME);
    887       } else if (current_frame_flags_ &
    888                  ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
    889         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    890       }
    891       break;
    892     case SYN_REPLY:
    893       if (current_frame_length_ < GetSynReplyMinimumSize()) {
    894         set_error(SPDY_INVALID_CONTROL_FRAME);
    895       } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
    896         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    897       }
    898       break;
    899     case RST_STREAM:
    900       // For SPDY versions < 4, the header has a fixed length.
    901       // For SPDY version 4 and up, the RST_STREAM frame may include optional
    902       // opaque data, so we only have a lower limit on the frame size.
    903       if ((current_frame_length_ != GetRstStreamMinimumSize() &&
    904            protocol_version() <= SPDY3) ||
    905           (current_frame_length_ < GetRstStreamMinimumSize() &&
    906            protocol_version() > SPDY3)) {
    907         set_error(SPDY_INVALID_CONTROL_FRAME);
    908       } else if (current_frame_flags_ != 0) {
    909         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    910       }
    911       break;
    912     case SETTINGS:
    913     {
    914       // Make sure that we have an integral number of 8-byte key/value pairs,
    915       // plus a 4-byte length field in SPDY3 and below.
    916       size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0);
    917       // Size of each key/value pair in bytes.
    918       size_t setting_size = SpdyConstants::GetSettingSize(protocol_version());
    919       if (current_frame_length_ < GetSettingsMinimumSize() ||
    920           (current_frame_length_ - GetControlFrameHeaderSize())
    921           % setting_size != values_prefix_size) {
    922         DLOG(WARNING) << "Invalid length for SETTINGS frame: "
    923                       << current_frame_length_;
    924         set_error(SPDY_INVALID_CONTROL_FRAME);
    925       } else if (protocol_version() <= SPDY3 &&
    926                  current_frame_flags_ &
    927                  ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
    928         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    929       } else if (protocol_version() > SPDY3 &&
    930                  current_frame_flags_ & ~SETTINGS_FLAG_ACK) {
    931         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    932       } else if (protocol_version() > SPDY3 &&
    933                  current_frame_flags_ & SETTINGS_FLAG_ACK &&
    934                  current_frame_length_ > GetSettingsMinimumSize()) {
    935         set_error(SPDY_INVALID_CONTROL_FRAME);
    936       }
    937       break;
    938     }
    939     case PING:
    940       if (current_frame_length_ != GetPingSize()) {
    941         set_error(SPDY_INVALID_CONTROL_FRAME);
    942       } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) ||
    943                  (current_frame_flags_ & ~PING_FLAG_ACK)) {
    944         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    945       }
    946       break;
    947     case GOAWAY:
    948       {
    949         // For SPDY version < 4, there are only mandatory fields and the header
    950         // has a fixed length. For SPDY version >= 4, optional opaque data may
    951         // be appended to the GOAWAY frame, thus there is only a minimal length
    952         // restriction.
    953         if ((current_frame_length_ != GetGoAwayMinimumSize() &&
    954              protocol_version() <= SPDY3) ||
    955             (current_frame_length_ < GetGoAwayMinimumSize() &&
    956              protocol_version() > SPDY3)) {
    957           set_error(SPDY_INVALID_CONTROL_FRAME);
    958         } else if (current_frame_flags_ != 0) {
    959           set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    960         }
    961         break;
    962       }
    963     case HEADERS:
    964       {
    965         size_t min_size = GetHeadersMinimumSize();
    966         if (protocol_version() > SPDY3 &&
    967             (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
    968           min_size += 4;
    969         }
    970         if (current_frame_length_ < min_size) {
    971           // TODO(mlavan): check here for HEADERS with no payload?
    972           // (not allowed in SPDY4)
    973           set_error(SPDY_INVALID_CONTROL_FRAME);
    974         } else if (protocol_version() <= SPDY3 &&
    975                    current_frame_flags_ & ~CONTROL_FLAG_FIN) {
    976           set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    977         } else if (protocol_version() > SPDY3 &&
    978                    current_frame_flags_ &
    979                        ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
    980                          HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT |
    981                          HEADERS_FLAG_PADDED)) {
    982           set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    983         }
    984       }
    985       break;
    986     case WINDOW_UPDATE:
    987       if (current_frame_length_ != GetWindowUpdateSize()) {
    988         set_error(SPDY_INVALID_CONTROL_FRAME);
    989       } else if (current_frame_flags_ != 0) {
    990         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    991       }
    992       break;
    993     case BLOCKED:
    994       if (current_frame_length_ != GetBlockedSize() ||
    995           protocol_version() <= SPDY3) {
    996         set_error(SPDY_INVALID_CONTROL_FRAME);
    997       } else if (current_frame_flags_ != 0) {
    998         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    999       }
   1000       break;
   1001     case PUSH_PROMISE:
   1002       if (current_frame_length_ < GetPushPromiseMinimumSize()) {
   1003         set_error(SPDY_INVALID_CONTROL_FRAME);
   1004       } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
   1005         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
   1006       } else if (protocol_version() > SPDY3 &&
   1007                  current_frame_flags_ &
   1008                      ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE |
   1009                        HEADERS_FLAG_PADDED)) {
   1010         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
   1011       }
   1012       break;
   1013     case CONTINUATION:
   1014       if (current_frame_length_ < GetContinuationMinimumSize() ||
   1015           protocol_version() <= SPDY3) {
   1016         set_error(SPDY_INVALID_CONTROL_FRAME);
   1017       } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) {
   1018         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
   1019       }
   1020       break;
   1021     case ALTSVC:
   1022       if (current_frame_length_ <= GetAltSvcMinimumSize()) {
   1023         set_error(SPDY_INVALID_CONTROL_FRAME);
   1024       } else if (current_frame_flags_ != 0) {
   1025         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
   1026       }
   1027       break;
   1028     case PRIORITY:
   1029       if (current_frame_length_ != GetPrioritySize() ||
   1030           protocol_version() <= SPDY3) {
   1031         set_error(SPDY_INVALID_CONTROL_FRAME);
   1032       } else if (current_frame_flags_ != 0) {
   1033         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
   1034       }
   1035       break;
   1036     default:
   1037       LOG(WARNING) << "Valid " << display_protocol_
   1038                    << " control frame with unhandled type: "
   1039                    << current_frame_type_;
   1040       // This branch should be unreachable because of the frame type bounds
   1041       // check above. However, we DLOG(FATAL) here in an effort to painfully
   1042       // club the head of the developer who failed to keep this file in sync
   1043       // with spdy_protocol.h.
   1044       DLOG(FATAL);
   1045       set_error(SPDY_INVALID_CONTROL_FRAME);
   1046       break;
   1047   }
   1048 
   1049   if (state_ == SPDY_ERROR) {
   1050     return;
   1051   }
   1052 
   1053   if (current_frame_length_ > GetControlFrameBufferMaxSize()) {
   1054     DLOG(WARNING) << "Received control frame with way too big of a payload: "
   1055                   << current_frame_length_;
   1056     set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   1057     return;
   1058   }
   1059 
   1060   if (current_frame_type_ == GOAWAY) {
   1061     CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD);
   1062     return;
   1063   }
   1064 
   1065   if (current_frame_type_ == RST_STREAM) {
   1066     CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD);
   1067     return;
   1068   }
   1069 
   1070   if (current_frame_type_ == ALTSVC) {
   1071     CHANGE_STATE(SPDY_ALTSVC_FRAME_PAYLOAD);
   1072     return;
   1073   }
   1074   // Determine the frame size without variable-length data.
   1075   int32 frame_size_without_variable_data;
   1076   switch (current_frame_type_) {
   1077     case SYN_STREAM:
   1078       syn_frame_processed_ = true;
   1079       frame_size_without_variable_data = GetSynStreamMinimumSize();
   1080       break;
   1081     case SYN_REPLY:
   1082       syn_frame_processed_ = true;
   1083       frame_size_without_variable_data = GetSynReplyMinimumSize();
   1084       break;
   1085     case SETTINGS:
   1086       frame_size_without_variable_data = GetSettingsMinimumSize();
   1087       break;
   1088     case HEADERS:
   1089       frame_size_without_variable_data = GetHeadersMinimumSize();
   1090       if (protocol_version() > SPDY3 &&
   1091           current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
   1092         frame_size_without_variable_data +=
   1093             kPriorityDependencyPayloadSize +
   1094             kPriorityWeightPayloadSize;
   1095       }
   1096       break;
   1097     case PUSH_PROMISE:
   1098       frame_size_without_variable_data = GetPushPromiseMinimumSize();
   1099       break;
   1100     case CONTINUATION:
   1101       frame_size_without_variable_data = GetContinuationMinimumSize();
   1102       break;
   1103     default:
   1104       frame_size_without_variable_data = -1;
   1105       break;
   1106   }
   1107 
   1108   if ((frame_size_without_variable_data == -1) &&
   1109       (current_frame_length_ > kControlFrameBufferSize)) {
   1110     // We should already be in an error state. Double-check.
   1111     DCHECK_EQ(SPDY_ERROR, state_);
   1112     if (state_ != SPDY_ERROR) {
   1113       LOG(DFATAL) << display_protocol_
   1114                   << " control frame buffer too small for fixed-length frame.";
   1115       set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   1116     }
   1117     return;
   1118   }
   1119 
   1120   if (frame_size_without_variable_data > 0) {
   1121     // We have a control frame with a header block. We need to parse the
   1122     // remainder of the control frame's header before we can parse the header
   1123     // block. The start of the header block varies with the control type.
   1124     DCHECK_GE(frame_size_without_variable_data,
   1125               static_cast<int32>(current_frame_buffer_length_));
   1126     remaining_control_header_ = frame_size_without_variable_data -
   1127         current_frame_buffer_length_;
   1128 
   1129     CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
   1130     return;
   1131   }
   1132 
   1133   CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
   1134 }
   1135 
   1136 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
   1137                                             size_t max_bytes) {
   1138   size_t bytes_to_read = std::min(*len, max_bytes);
   1139   if (bytes_to_read > 0) {
   1140     DCHECK_GE(kControlFrameBufferSize,
   1141               current_frame_buffer_length_ + bytes_to_read);
   1142     memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
   1143            *data,
   1144            bytes_to_read);
   1145     current_frame_buffer_length_ += bytes_to_read;
   1146     *data += bytes_to_read;
   1147     *len -= bytes_to_read;
   1148   }
   1149   return bytes_to_read;
   1150 }
   1151 
   1152 size_t SpdyFramer::GetSerializedLength(
   1153     const SpdyMajorVersion spdy_version,
   1154     const SpdyHeaderBlock* headers) {
   1155   const size_t num_name_value_pairs_size
   1156       = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
   1157   const size_t length_of_name_size = num_name_value_pairs_size;
   1158   const size_t length_of_value_size = num_name_value_pairs_size;
   1159 
   1160   size_t total_length = num_name_value_pairs_size;
   1161   for (SpdyHeaderBlock::const_iterator it = headers->begin();
   1162        it != headers->end();
   1163        ++it) {
   1164     // We add space for the length of the name and the length of the value as
   1165     // well as the length of the name and the length of the value.
   1166     total_length += length_of_name_size + it->first.size() +
   1167                     length_of_value_size + it->second.size();
   1168   }
   1169   return total_length;
   1170 }
   1171 
   1172 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
   1173                                   const SpdyMajorVersion spdy_version,
   1174                                   const SpdyHeaderBlock* headers) {
   1175   if (spdy_version < SPDY3) {
   1176     frame->WriteUInt16(headers->size());  // Number of headers.
   1177   } else {
   1178     frame->WriteUInt32(headers->size());  // Number of headers.
   1179   }
   1180   SpdyHeaderBlock::const_iterator it;
   1181   for (it = headers->begin(); it != headers->end(); ++it) {
   1182     if (spdy_version < SPDY3) {
   1183       frame->WriteString(it->first);
   1184       frame->WriteString(it->second);
   1185     } else {
   1186       frame->WriteStringPiece32(it->first);
   1187       frame->WriteStringPiece32(it->second);
   1188     }
   1189   }
   1190 }
   1191 
   1192 // TODO(phajdan.jr): Clean up after we no longer need
   1193 // to workaround http://crbug.com/139744.
   1194 #if !defined(USE_SYSTEM_ZLIB)
   1195 
   1196 // These constants are used by zlib to differentiate between normal data and
   1197 // cookie data. Cookie data is handled specially by zlib when compressing.
   1198 enum ZDataClass {
   1199   // kZStandardData is compressed normally, save that it will never match
   1200   // against any other class of data in the window.
   1201   kZStandardData = Z_CLASS_STANDARD,
   1202   // kZCookieData is compressed in its own Huffman blocks and only matches in
   1203   // its entirety and only against other kZCookieData blocks. Any matches must
   1204   // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
   1205   // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
   1206   // prefix matches.
   1207   kZCookieData = Z_CLASS_COOKIE,
   1208   // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
   1209   // against the window.
   1210   kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
   1211 };
   1212 
   1213 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
   1214 // needed when switching between classes of data.
   1215 static void WriteZ(const base::StringPiece& data,
   1216                    ZDataClass clas,
   1217                    z_stream* out) {
   1218   int rv;
   1219 
   1220   // If we are switching from standard to non-standard data then we need to end
   1221   // the current Huffman context to avoid it leaking between them.
   1222   if (out->clas == kZStandardData &&
   1223       clas != kZStandardData) {
   1224     out->avail_in = 0;
   1225     rv = deflate(out, Z_PARTIAL_FLUSH);
   1226     DCHECK_EQ(Z_OK, rv);
   1227     DCHECK_EQ(0u, out->avail_in);
   1228     DCHECK_LT(0u, out->avail_out);
   1229   }
   1230 
   1231   out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
   1232   out->avail_in = data.size();
   1233   out->clas = clas;
   1234   if (clas == kZStandardData) {
   1235     rv = deflate(out, Z_NO_FLUSH);
   1236   } else {
   1237     rv = deflate(out, Z_PARTIAL_FLUSH);
   1238   }
   1239   if (!data.empty()) {
   1240     // If we didn't provide any data then zlib will return Z_BUF_ERROR.
   1241     DCHECK_EQ(Z_OK, rv);
   1242   }
   1243   DCHECK_EQ(0u, out->avail_in);
   1244   DCHECK_LT(0u, out->avail_out);
   1245 }
   1246 
   1247 // WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
   1248 static void WriteLengthZ(size_t n,
   1249                          unsigned length,
   1250                          ZDataClass clas,
   1251                          z_stream* out) {
   1252   char buf[4];
   1253   DCHECK_LE(length, sizeof(buf));
   1254   for (unsigned i = 1; i <= length; i++) {
   1255     buf[length - i] = n;
   1256     n >>= 8;
   1257   }
   1258   WriteZ(base::StringPiece(buf, length), clas, out);
   1259 }
   1260 
   1261 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
   1262 // manner that resists the length of the compressed data from compromising
   1263 // cookie data.
   1264 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
   1265                                      z_stream* z) const {
   1266   unsigned length_length = 4;
   1267   if (spdy_version_ < 3)
   1268     length_length = 2;
   1269 
   1270   WriteLengthZ(headers->size(), length_length, kZStandardData, z);
   1271 
   1272   std::map<std::string, std::string>::const_iterator it;
   1273   for (it = headers->begin(); it != headers->end(); ++it) {
   1274     WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
   1275     WriteZ(it->first, kZStandardData, z);
   1276 
   1277     if (it->first == "cookie") {
   1278       // We require the cookie values (save for the last) to end with a
   1279       // semicolon and (save for the first) to start with a space. This is
   1280       // typically the format that we are given them in but we reserialize them
   1281       // to be sure.
   1282 
   1283       std::vector<base::StringPiece> cookie_values;
   1284       size_t cookie_length = 0;
   1285       base::StringPiece cookie_data(it->second);
   1286 
   1287       for (;;) {
   1288         while (!cookie_data.empty() &&
   1289                (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
   1290           cookie_data.remove_prefix(1);
   1291         }
   1292         if (cookie_data.empty())
   1293           break;
   1294 
   1295         size_t i;
   1296         for (i = 0; i < cookie_data.size(); i++) {
   1297           if (cookie_data[i] == ';')
   1298             break;
   1299         }
   1300         if (i < cookie_data.size()) {
   1301           if (!IsCookieEmpty(cookie_data.substr(0, i))) {
   1302             cookie_values.push_back(cookie_data.substr(0, i));
   1303             cookie_length += i + 2 /* semicolon and space */;
   1304           }
   1305           cookie_data.remove_prefix(i + 1);
   1306         } else {
   1307           if (!IsCookieEmpty(cookie_data)) {
   1308             cookie_values.push_back(cookie_data);
   1309             cookie_length += cookie_data.size();
   1310           } else if (cookie_length > 2) {
   1311             cookie_length -= 2 /* compensate for previously added length */;
   1312           }
   1313           cookie_data.remove_prefix(i);
   1314         }
   1315       }
   1316 
   1317       WriteLengthZ(cookie_length, length_length, kZStandardData, z);
   1318       for (size_t i = 0; i < cookie_values.size(); i++) {
   1319         std::string cookie;
   1320         // Since zlib will only back-reference complete cookies, a cookie that
   1321         // is currently last (and so doesn't have a trailing semicolon) won't
   1322         // match if it's later in a non-final position. The same is true of
   1323         // the first cookie.
   1324         if (i == 0 && cookie_values.size() == 1) {
   1325           cookie = cookie_values[i].as_string();
   1326         } else if (i == 0) {
   1327           cookie = cookie_values[i].as_string() + ";";
   1328         } else if (i < cookie_values.size() - 1) {
   1329           cookie = " " + cookie_values[i].as_string() + ";";
   1330         } else {
   1331           cookie = " " + cookie_values[i].as_string();
   1332         }
   1333         WriteZ(cookie, kZCookieData, z);
   1334       }
   1335     } else if (it->first == "accept" ||
   1336                it->first == "accept-charset" ||
   1337                it->first == "accept-encoding" ||
   1338                it->first == "accept-language" ||
   1339                it->first == "host" ||
   1340                it->first == "version" ||
   1341                it->first == "method" ||
   1342                it->first == "scheme" ||
   1343                it->first == ":host" ||
   1344                it->first == ":version" ||
   1345                it->first == ":method" ||
   1346                it->first == ":scheme" ||
   1347                it->first == "user-agent") {
   1348       WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
   1349       WriteZ(it->second, kZStandardData, z);
   1350     } else {
   1351       // Non-whitelisted headers are Huffman compressed in their own block, but
   1352       // don't match against the window.
   1353       WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
   1354       WriteZ(it->second, kZHuffmanOnlyData, z);
   1355     }
   1356   }
   1357 
   1358   z->avail_in = 0;
   1359   int rv = deflate(z, Z_SYNC_FLUSH);
   1360   DCHECK_EQ(Z_OK, rv);
   1361   z->clas = kZStandardData;
   1362 }
   1363 
   1364 #endif  // !defined(USE_SYSTEM_ZLIB)
   1365 
   1366 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
   1367                                                         size_t len) {
   1368   DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
   1369   const size_t original_len = len;
   1370 
   1371   if (remaining_control_header_ > 0) {
   1372     size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
   1373                                                  remaining_control_header_);
   1374     remaining_control_header_ -= bytes_read;
   1375     remaining_data_length_ -= bytes_read;
   1376   }
   1377 
   1378   if (remaining_control_header_ == 0) {
   1379     SpdyFrameReader reader(current_frame_buffer_.get(),
   1380                            current_frame_buffer_length_);
   1381     reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
   1382 
   1383     switch (current_frame_type_) {
   1384       case SYN_STREAM:
   1385         {
   1386           DCHECK_GE(SPDY3, protocol_version());
   1387           bool successful_read = true;
   1388           successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1389           DCHECK(successful_read);
   1390           if (current_frame_stream_id_ == 0) {
   1391             set_error(SPDY_INVALID_CONTROL_FRAME);
   1392             break;
   1393           }
   1394 
   1395           SpdyStreamId associated_to_stream_id = kInvalidStream;
   1396           successful_read = reader.ReadUInt31(&associated_to_stream_id);
   1397           DCHECK(successful_read);
   1398 
   1399           SpdyPriority priority = 0;
   1400           successful_read = reader.ReadUInt8(&priority);
   1401           DCHECK(successful_read);
   1402           if (protocol_version() <= SPDY2) {
   1403             priority = priority >> 6;
   1404           } else {
   1405             priority = priority >> 5;
   1406           }
   1407 
   1408          // Seek past unused byte; used to be credential slot in SPDY 3.
   1409          reader.Seek(1);
   1410 
   1411           DCHECK(reader.IsDoneReading());
   1412           if (debug_visitor_) {
   1413             debug_visitor_->OnReceiveCompressedFrame(
   1414                 current_frame_stream_id_,
   1415                 current_frame_type_,
   1416                 current_frame_length_);
   1417           }
   1418           visitor_->OnSynStream(
   1419               current_frame_stream_id_,
   1420               associated_to_stream_id,
   1421               priority,
   1422               (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
   1423               (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
   1424         }
   1425         CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   1426         break;
   1427       case SETTINGS:
   1428         if (protocol_version() > SPDY3 &&
   1429             current_frame_flags_ & SETTINGS_FLAG_ACK) {
   1430           visitor_->OnSettingsAck();
   1431           CHANGE_STATE(SPDY_AUTO_RESET);
   1432         } else {
   1433           visitor_->OnSettings(current_frame_flags_ &
   1434               SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
   1435           CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
   1436         }
   1437         break;
   1438       case SYN_REPLY:
   1439       case HEADERS:
   1440         // SYN_REPLY and HEADERS are the same, save for the visitor call.
   1441         {
   1442           if (protocol_version() > SPDY3) {
   1443             DCHECK_EQ(HEADERS, current_frame_type_);
   1444           }
   1445           bool successful_read = true;
   1446           if (protocol_version() <= SPDY3) {
   1447             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1448             DCHECK(successful_read);
   1449           }
   1450           if (current_frame_stream_id_ == 0) {
   1451             set_error(SPDY_INVALID_CONTROL_FRAME);
   1452             break;
   1453           }
   1454           if (protocol_version() <= SPDY2) {
   1455             // SPDY 2 had two unused bytes here. Seek past them.
   1456             reader.Seek(2);
   1457           }
   1458           if (protocol_version() > SPDY3 &&
   1459              !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
   1460              current_frame_type_ == HEADERS) {
   1461             expect_continuation_ = current_frame_stream_id_;
   1462             end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
   1463           }
   1464           const bool has_priority =
   1465               (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
   1466           uint32 priority = 0;
   1467           if (protocol_version() > SPDY3 && has_priority) {
   1468             // TODO(jgraettinger): Process dependency rather than ignoring it.
   1469             reader.Seek(kPriorityDependencyPayloadSize);
   1470             uint8 weight = 0;
   1471             successful_read = reader.ReadUInt8(&weight);
   1472             if (successful_read) {
   1473               priority = MapWeightToPriority(weight);
   1474             }
   1475           }
   1476           DCHECK(reader.IsDoneReading());
   1477           if (debug_visitor_) {
   1478             // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
   1479             SpdyFrameType reported_type = current_frame_type_;
   1480             if (protocol_version() > SPDY3 && has_priority) {
   1481               reported_type = SYN_STREAM;
   1482             }
   1483             debug_visitor_->OnReceiveCompressedFrame(
   1484                 current_frame_stream_id_,
   1485                 reported_type,
   1486                 current_frame_length_);
   1487           }
   1488           if (current_frame_type_ == SYN_REPLY) {
   1489             visitor_->OnSynReply(
   1490                 current_frame_stream_id_,
   1491                 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
   1492           } else if (protocol_version() > SPDY3 &&
   1493               current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
   1494             // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes
   1495             // can be made independent of wire changes.
   1496             visitor_->OnSynStream(
   1497                 current_frame_stream_id_,
   1498                 0,  // associated_to_stream_id
   1499                 priority,
   1500                 current_frame_flags_ & CONTROL_FLAG_FIN,
   1501                 false);  // unidirectional
   1502           } else {
   1503             visitor_->OnHeaders(
   1504                 current_frame_stream_id_,
   1505                 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
   1506                 expect_continuation_ == 0);
   1507           }
   1508         }
   1509         CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
   1510         break;
   1511       case PUSH_PROMISE:
   1512         {
   1513           DCHECK_LT(SPDY3, protocol_version());
   1514           if (current_frame_stream_id_ == 0) {
   1515             set_error(SPDY_INVALID_CONTROL_FRAME);
   1516             break;
   1517           }
   1518           SpdyStreamId promised_stream_id = kInvalidStream;
   1519           bool successful_read = reader.ReadUInt31(&promised_stream_id);
   1520           DCHECK(successful_read);
   1521           DCHECK(reader.IsDoneReading());
   1522           if (promised_stream_id == 0) {
   1523             set_error(SPDY_INVALID_CONTROL_FRAME);
   1524             break;
   1525           }
   1526           if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) {
   1527             expect_continuation_ = current_frame_stream_id_;
   1528           }
   1529           if (debug_visitor_) {
   1530             debug_visitor_->OnReceiveCompressedFrame(
   1531                 current_frame_stream_id_,
   1532                 current_frame_type_,
   1533                 current_frame_length_);
   1534           }
   1535           visitor_->OnPushPromise(current_frame_stream_id_,
   1536                                   promised_stream_id,
   1537                                   (current_frame_flags_ &
   1538                                    PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
   1539         }
   1540         CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
   1541         break;
   1542       case CONTINUATION:
   1543         {
   1544           // Check to make sure the stream id of the current frame is
   1545           // the same as that of the preceding frame.
   1546           // If we're at this point we should already know that
   1547           // expect_continuation_ != 0, so this doubles as a check
   1548           // that current_frame_stream_id != 0.
   1549           if (current_frame_stream_id_ != expect_continuation_) {
   1550             set_error(SPDY_INVALID_CONTROL_FRAME);
   1551             break;
   1552           }
   1553           if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) {
   1554             expect_continuation_ = 0;
   1555           }
   1556           if (debug_visitor_) {
   1557             debug_visitor_->OnReceiveCompressedFrame(
   1558                 current_frame_stream_id_,
   1559                 current_frame_type_,
   1560                 current_frame_length_);
   1561           }
   1562           visitor_->OnContinuation(current_frame_stream_id_,
   1563                                    (current_frame_flags_ &
   1564                                     HEADERS_FLAG_END_HEADERS) != 0);
   1565         }
   1566         CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   1567         break;
   1568       default:
   1569         DCHECK(false);
   1570     }
   1571   }
   1572   return original_len - len;
   1573 }
   1574 
   1575 // Does not buffer the control payload. Instead, either passes directly to the
   1576 // visitor or decompresses and then passes directly to the visitor, via
   1577 // IncrementallyDeliverControlFrameHeaderData() or
   1578 // IncrementallyDecompressControlFrameHeaderData() respectively.
   1579 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
   1580                                                   size_t data_len,
   1581                                                   bool is_hpack_header_block) {
   1582   DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
   1583 
   1584   bool processed_successfully = true;
   1585   if (current_frame_type_ != SYN_STREAM &&
   1586       current_frame_type_ != SYN_REPLY &&
   1587       current_frame_type_ != HEADERS &&
   1588       current_frame_type_ != PUSH_PROMISE &&
   1589       current_frame_type_ != CONTINUATION) {
   1590     LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
   1591   }
   1592   size_t process_bytes = std::min(
   1593       data_len, remaining_data_length_ - remaining_padding_payload_length_);
   1594   if (is_hpack_header_block) {
   1595     if (!GetHpackDecoder()->HandleControlFrameHeadersData(
   1596             current_frame_stream_id_, data, process_bytes)) {
   1597       // TODO(jgraettinger): Finer-grained HPACK error codes.
   1598       set_error(SPDY_DECOMPRESS_FAILURE);
   1599       processed_successfully = false;
   1600     }
   1601   } else if (process_bytes > 0) {
   1602     if (enable_compression_ && protocol_version() <= SPDY3) {
   1603       processed_successfully = IncrementallyDecompressControlFrameHeaderData(
   1604           current_frame_stream_id_, data, process_bytes);
   1605     } else {
   1606       processed_successfully = IncrementallyDeliverControlFrameHeaderData(
   1607           current_frame_stream_id_, data, process_bytes);
   1608     }
   1609   }
   1610   remaining_data_length_ -= process_bytes;
   1611 
   1612   // Handle the case that there is no futher data in this frame.
   1613   if (remaining_data_length_ == remaining_padding_payload_length_ &&
   1614       processed_successfully) {
   1615     if (expect_continuation_ == 0) {
   1616       if (is_hpack_header_block) {
   1617         if (!GetHpackDecoder()->HandleControlFrameHeadersComplete(
   1618                 current_frame_stream_id_)) {
   1619           set_error(SPDY_DECOMPRESS_FAILURE);
   1620           processed_successfully = false;
   1621         } else {
   1622           // TODO(jgraettinger): To be removed with migration to
   1623           // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
   1624           // block, delivered via reentrant call to
   1625           // ProcessControlFrameHeaderBlock().
   1626           DeliverHpackBlockAsSpdy3Block();
   1627           return process_bytes;
   1628         }
   1629       } else {
   1630         // The complete header block has been delivered. We send a zero-length
   1631         // OnControlFrameHeaderData() to indicate this.
   1632         visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
   1633       }
   1634     }
   1635     if (processed_successfully) {
   1636       CHANGE_STATE(SPDY_CONSUME_PADDING);
   1637     }
   1638   }
   1639 
   1640   // Handle error.
   1641   if (!processed_successfully) {
   1642     return data_len;
   1643   }
   1644 
   1645   // Return amount processed.
   1646   return process_bytes;
   1647 }
   1648 
   1649 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
   1650                                                size_t data_len) {
   1651   DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
   1652   DCHECK_EQ(SETTINGS, current_frame_type_);
   1653   size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
   1654   size_t processed_bytes = 0;
   1655 
   1656   size_t setting_size = SpdyConstants::GetSettingSize(protocol_version());
   1657 
   1658   // Loop over our incoming data.
   1659   while (unprocessed_bytes > 0) {
   1660     // Process up to one setting at a time.
   1661     size_t processing = std::min(
   1662         unprocessed_bytes,
   1663         static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len));
   1664 
   1665     // Check if we have a complete setting in our input.
   1666     if (processing == setting_size) {
   1667       // Parse the setting directly out of the input without buffering.
   1668       if (!ProcessSetting(data + processed_bytes)) {
   1669         set_error(SPDY_INVALID_CONTROL_FRAME);
   1670         return processed_bytes;
   1671       }
   1672     } else {
   1673       // Continue updating settings_scratch_.setting_buf.
   1674       memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
   1675              data + processed_bytes,
   1676              processing);
   1677       settings_scratch_.setting_buf_len += processing;
   1678 
   1679       // Check if we have a complete setting buffered.
   1680       if (settings_scratch_.setting_buf_len == setting_size) {
   1681         if (!ProcessSetting(settings_scratch_.setting_buf)) {
   1682           set_error(SPDY_INVALID_CONTROL_FRAME);
   1683           return processed_bytes;
   1684         }
   1685         // Reset settings_scratch_.setting_buf for our next setting.
   1686         settings_scratch_.setting_buf_len = 0;
   1687       }
   1688     }
   1689 
   1690     // Iterate.
   1691     unprocessed_bytes -= processing;
   1692     processed_bytes += processing;
   1693   }
   1694 
   1695   // Check if we're done handling this SETTINGS frame.
   1696   remaining_data_length_ -= processed_bytes;
   1697   if (remaining_data_length_ == 0) {
   1698     visitor_->OnSettingsEnd();
   1699     CHANGE_STATE(SPDY_AUTO_RESET);
   1700   }
   1701 
   1702   return processed_bytes;
   1703 }
   1704 
   1705 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
   1706   DCHECK_LT(SPDY3, protocol_version());
   1707   DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
   1708 
   1709   const SpdyNameValueBlock& block = GetHpackDecoder()->decoded_block();
   1710   if (block.empty()) {
   1711     // Special-case this to make tests happy.
   1712     ProcessControlFrameHeaderBlock(NULL, 0, false);
   1713     return;
   1714   }
   1715   SpdyFrameBuilder builder(
   1716       GetSerializedLength(protocol_version(), &block),
   1717       SPDY3);
   1718 
   1719   SerializeNameValueBlockWithoutCompression(&builder, block);
   1720   scoped_ptr<SpdyFrame> frame(builder.take());
   1721 
   1722   // Preserve padding length, and reset it after the re-entrant call.
   1723   size_t remaining_padding = remaining_padding_payload_length_;
   1724 
   1725   remaining_padding_payload_length_ = 0;
   1726   remaining_data_length_ = frame->size();
   1727 
   1728   ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
   1729 
   1730   remaining_padding_payload_length_ = remaining_padding;
   1731   remaining_data_length_ = remaining_padding;
   1732 }
   1733 
   1734 bool SpdyFramer::ProcessSetting(const char* data) {
   1735   int id_field;
   1736   SpdySettingsIds id;
   1737   uint8 flags = 0;
   1738   uint32 value;
   1739 
   1740   // Extract fields.
   1741   // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
   1742   if (protocol_version() <= SPDY3) {
   1743     const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
   1744     SettingsFlagsAndId id_and_flags =
   1745       SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire);
   1746     id_field = id_and_flags.id();
   1747     flags = id_and_flags.flags();
   1748     value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
   1749   } else {
   1750     id_field = ntohs(*(reinterpret_cast<const uint16*>(data)));
   1751     value = ntohl(*(reinterpret_cast<const uint32*>(data + 2)));
   1752   }
   1753 
   1754   // Validate id.
   1755   if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) {
   1756     DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field;
   1757     if (protocol_version() <= SPDY3) {
   1758       return false;
   1759     } else {
   1760       // In HTTP2 we ignore unknown settings for extensibility.
   1761       return true;
   1762     }
   1763   }
   1764   id = SpdyConstants::ParseSettingId(protocol_version(), id_field);
   1765 
   1766   if (protocol_version() <= SPDY3) {
   1767     // Detect duplicates.
   1768     if (id <= settings_scratch_.last_setting_id) {
   1769       DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
   1770                     << " in " << display_protocol_ << " SETTINGS frame "
   1771                     << "(last setting id was "
   1772                     << settings_scratch_.last_setting_id << ").";
   1773       return false;
   1774     }
   1775     settings_scratch_.last_setting_id = id;
   1776 
   1777     // Validate flags.
   1778     uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
   1779     if ((flags & ~(kFlagsMask)) != 0) {
   1780       DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
   1781                     << flags;
   1782       return false;
   1783     }
   1784   }
   1785 
   1786   // Validation succeeded. Pass on to visitor.
   1787   visitor_->OnSetting(id, flags, value);
   1788   return true;
   1789 }
   1790 
   1791 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
   1792   size_t original_len = len;
   1793   size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
   1794                                                remaining_data_length_);
   1795   remaining_data_length_ -= bytes_read;
   1796   if (remaining_data_length_ == 0) {
   1797     SpdyFrameReader reader(current_frame_buffer_.get(),
   1798                            current_frame_buffer_length_);
   1799     reader.Seek(GetControlFrameHeaderSize());  // Skip frame header.
   1800 
   1801     // Use frame-specific handlers.
   1802     switch (current_frame_type_) {
   1803       case PING: {
   1804           SpdyPingId id = 0;
   1805           bool is_ack = protocol_version() > SPDY3 &&
   1806               (current_frame_flags_ & PING_FLAG_ACK);
   1807           bool successful_read = true;
   1808           if (protocol_version() <= SPDY3) {
   1809             uint32 id32 = 0;
   1810             successful_read = reader.ReadUInt32(&id32);
   1811             id = id32;
   1812           } else {
   1813             successful_read = reader.ReadUInt64(&id);
   1814           }
   1815           DCHECK(successful_read);
   1816           DCHECK(reader.IsDoneReading());
   1817           visitor_->OnPing(id, is_ack);
   1818         }
   1819         break;
   1820       case WINDOW_UPDATE: {
   1821           uint32 delta_window_size = 0;
   1822           bool successful_read = true;
   1823           if (protocol_version() <= SPDY3) {
   1824             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1825             DCHECK(successful_read);
   1826           }
   1827           successful_read = reader.ReadUInt32(&delta_window_size);
   1828           DCHECK(successful_read);
   1829           DCHECK(reader.IsDoneReading());
   1830           visitor_->OnWindowUpdate(current_frame_stream_id_,
   1831                                    delta_window_size);
   1832         }
   1833         break;
   1834       case BLOCKED: {
   1835           DCHECK_LT(SPDY3, protocol_version());
   1836           DCHECK(reader.IsDoneReading());
   1837           visitor_->OnBlocked(current_frame_stream_id_);
   1838         }
   1839         break;
   1840       case PRIORITY: {
   1841           DCHECK_LT(SPDY3, protocol_version());
   1842           uint32 parent_stream_id;
   1843           uint8 weight;
   1844           bool exclusive;
   1845           bool successful_read = true;
   1846           successful_read = reader.ReadUInt32(&parent_stream_id);
   1847           DCHECK(successful_read);
   1848           // Exclusivity is indicated by a single bit flag.
   1849           exclusive = (parent_stream_id >> 31) != 0;
   1850           // Zero out the highest-order bit to get the parent stream id.
   1851           parent_stream_id &= 0x7fffffff;
   1852           successful_read = reader.ReadUInt8(&weight);
   1853           DCHECK(successful_read);
   1854           DCHECK(reader.IsDoneReading());
   1855           visitor_->OnPriority(
   1856               current_frame_stream_id_, parent_stream_id, weight, exclusive);
   1857         }
   1858         break;
   1859       default:
   1860         // Unreachable.
   1861         LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
   1862     }
   1863 
   1864     CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
   1865   }
   1866   return original_len - len;
   1867 }
   1868 
   1869 size_t SpdyFramer::ProcessGoAwayFramePayload(const char* data, size_t len) {
   1870   if (len == 0) {
   1871     return 0;
   1872   }
   1873   // Clamp to the actual remaining payload.
   1874   if (len > remaining_data_length_) {
   1875     len = remaining_data_length_;
   1876   }
   1877   size_t original_len = len;
   1878 
   1879   // Check if we had already read enough bytes to parse the GOAWAY header.
   1880   const size_t header_size = GetGoAwayMinimumSize();
   1881   size_t unread_header_bytes = header_size - current_frame_buffer_length_;
   1882   bool already_parsed_header = (unread_header_bytes == 0);
   1883   if (!already_parsed_header) {
   1884     // Buffer the new GOAWAY header bytes we got.
   1885     UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);
   1886 
   1887     // Do we have enough to parse the constant size GOAWAY header?
   1888     if (current_frame_buffer_length_ == header_size) {
   1889       // Parse out the last good stream id.
   1890       SpdyFrameReader reader(current_frame_buffer_.get(),
   1891                              current_frame_buffer_length_);
   1892       reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
   1893       bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1894       DCHECK(successful_read);
   1895 
   1896       // In SPDYv3 and up, frames also specify a status code - parse it out.
   1897       SpdyGoAwayStatus status = GOAWAY_OK;
   1898       if (protocol_version() >= SPDY3) {
   1899         uint32 status_raw = GOAWAY_OK;
   1900         successful_read = reader.ReadUInt32(&status_raw);
   1901         DCHECK(successful_read);
   1902         if (SpdyConstants::IsValidGoAwayStatus(protocol_version(),
   1903                                                status_raw)) {
   1904           status = SpdyConstants::ParseGoAwayStatus(protocol_version(),
   1905                                                     status_raw);
   1906         } else {
   1907           if (protocol_version() > SPDY3) {
   1908             // Treat unrecognized status codes as INTERNAL_ERROR as
   1909             // recommended by the HTTP/2 spec.
   1910             status = GOAWAY_INTERNAL_ERROR;
   1911           }
   1912         }
   1913       }
   1914       // Finished parsing the GOAWAY header, call frame handler.
   1915       visitor_->OnGoAway(current_frame_stream_id_, status);
   1916     }
   1917   }
   1918 
   1919   // Handle remaining data as opaque.
   1920   bool processed_successfully = true;
   1921   if (len > 0) {
   1922     processed_successfully = visitor_->OnGoAwayFrameData(data, len);
   1923   }
   1924   remaining_data_length_ -= original_len;
   1925   if (!processed_successfully) {
   1926     set_error(SPDY_GOAWAY_FRAME_CORRUPT);
   1927   } else if (remaining_data_length_ == 0) {
   1928     // Signal that there is not more opaque data.
   1929     visitor_->OnGoAwayFrameData(NULL, 0);
   1930     CHANGE_STATE(SPDY_AUTO_RESET);
   1931   }
   1932   return original_len;
   1933 }
   1934 
   1935 size_t SpdyFramer::ProcessRstStreamFramePayload(const char* data, size_t len) {
   1936   if (len == 0) {
   1937     return 0;
   1938   }
   1939   // Clamp to the actual remaining payload.
   1940   if (len > remaining_data_length_) {
   1941     len = remaining_data_length_;
   1942   }
   1943   size_t original_len = len;
   1944 
   1945   // Check if we had already read enough bytes to parse the fixed-length portion
   1946   // of the RST_STREAM frame.
   1947   const size_t header_size = GetRstStreamMinimumSize();
   1948   size_t unread_header_bytes = header_size - current_frame_buffer_length_;
   1949   bool already_parsed_header = (unread_header_bytes == 0);
   1950   if (!already_parsed_header) {
   1951     // Buffer the new RST_STREAM header bytes we got.
   1952     UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);
   1953 
   1954     // Do we have enough to parse the constant size RST_STREAM header?
   1955     if (current_frame_buffer_length_ == header_size) {
   1956       // Parse out the last good stream id.
   1957       SpdyFrameReader reader(current_frame_buffer_.get(),
   1958                              current_frame_buffer_length_);
   1959       reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
   1960       if (protocol_version() <= SPDY3) {
   1961         bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1962         DCHECK(successful_read);
   1963       }
   1964 
   1965       SpdyRstStreamStatus status = RST_STREAM_INVALID;
   1966       uint32 status_raw = status;
   1967       bool successful_read = reader.ReadUInt32(&status_raw);
   1968       DCHECK(successful_read);
   1969       if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
   1970                                                 status_raw)) {
   1971         status = static_cast<SpdyRstStreamStatus>(status_raw);
   1972       } else {
   1973         if (protocol_version() > SPDY3) {
   1974           // Treat unrecognized status codes as INTERNAL_ERROR as
   1975           // recommended by the HTTP/2 spec.
   1976           status = RST_STREAM_INTERNAL_ERROR;
   1977         }
   1978       }
   1979       // Finished parsing the RST_STREAM header, call frame handler.
   1980       visitor_->OnRstStream(current_frame_stream_id_, status);
   1981     }
   1982   }
   1983 
   1984   // Handle remaining data as opaque.
   1985   bool processed_successfully = true;
   1986   if (len > 0) {
   1987     processed_successfully = visitor_->OnRstStreamFrameData(data, len);
   1988   }
   1989   remaining_data_length_ -= original_len;
   1990   if (!processed_successfully) {
   1991     set_error(SPDY_RST_STREAM_FRAME_CORRUPT);
   1992   } else if (remaining_data_length_ == 0) {
   1993     // Signal that there is not more opaque data.
   1994     visitor_->OnRstStreamFrameData(NULL, 0);
   1995     CHANGE_STATE(SPDY_AUTO_RESET);
   1996   }
   1997   return original_len;
   1998 }
   1999 
   2000 size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) {
   2001   if (len == 0) {
   2002     return 0;
   2003   }
   2004 
   2005   // Clamp to the actual remaining payload.
   2006   len = std::min(len, remaining_data_length_);
   2007 
   2008   size_t processed_bytes = 0;
   2009   size_t processing = 0;
   2010   size_t bytes_remaining;
   2011   char* buffer;
   2012   size_t* buffer_len;
   2013 
   2014   while (len > 0) {
   2015     if (altsvc_scratch_.pid_len == 0) {
   2016       // The size of the frame up to the PID_LEN field.
   2017       size_t fixed_len_portion = GetAltSvcMinimumSize() - 1;
   2018       bytes_remaining = fixed_len_portion - current_frame_buffer_length_;
   2019       processing = std::min(len, bytes_remaining);
   2020       // Buffer the new ALTSVC bytes we got.
   2021       UpdateCurrentFrameBuffer(&data, &len, processing);
   2022 
   2023       // Do we have enough to parse the length of the protocol id?
   2024       if (current_frame_buffer_length_ == fixed_len_portion) {
   2025         // Parse out the max age, port, and pid_len.
   2026         SpdyFrameReader reader(current_frame_buffer_.get(),
   2027                                current_frame_buffer_length_);
   2028         reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
   2029         bool successful_read = reader.ReadUInt32(&altsvc_scratch_.max_age);
   2030         reader.ReadUInt16(&altsvc_scratch_.port);
   2031         reader.Seek(1);  // Reserved byte.
   2032         successful_read = successful_read &&
   2033                           reader.ReadUInt8(&altsvc_scratch_.pid_len);
   2034         DCHECK(successful_read);
   2035         // Sanity check length value.
   2036         if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len >=
   2037             current_frame_length_) {
   2038           set_error(SPDY_INVALID_CONTROL_FRAME);
   2039           return 0;
   2040         }
   2041         altsvc_scratch_.protocol_id.reset(
   2042             new char[size_t(altsvc_scratch_.pid_len)]);
   2043       }
   2044       processed_bytes += processing;
   2045       continue;
   2046     } else if (altsvc_scratch_.pid_buf_len < altsvc_scratch_.pid_len) {
   2047       // Buffer protocol id field as in comes in.
   2048       buffer = altsvc_scratch_.protocol_id.get();
   2049       buffer_len = &altsvc_scratch_.pid_buf_len;
   2050       bytes_remaining = altsvc_scratch_.pid_len - altsvc_scratch_.pid_buf_len;
   2051     } else if (altsvc_scratch_.host_len == 0) {
   2052       // Parse out the host length.
   2053       processing = 1;
   2054       altsvc_scratch_.host_len = *reinterpret_cast<const uint8*>(data);
   2055       // Sanity check length value.
   2056       if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len +
   2057           altsvc_scratch_.host_len > current_frame_length_) {
   2058         set_error(SPDY_INVALID_CONTROL_FRAME);
   2059         return 0;
   2060       }
   2061       altsvc_scratch_.host.reset(new char[altsvc_scratch_.host_len]);
   2062       // Once we have host length, we can also determine the origin length
   2063       // by process of elimination.
   2064       altsvc_scratch_.origin_len = current_frame_length_ -
   2065         GetAltSvcMinimumSize() -
   2066         altsvc_scratch_.pid_len -
   2067         altsvc_scratch_.host_len;
   2068       if (altsvc_scratch_.origin_len > 0) {
   2069         altsvc_scratch_.origin.reset(new char[altsvc_scratch_.origin_len]);
   2070       }
   2071       data += processing;
   2072       processed_bytes += processing;
   2073       len -= processing;
   2074       continue;
   2075     } else if (altsvc_scratch_.host_buf_len < altsvc_scratch_.host_len) {
   2076       // Buffer host field as it comes in.
   2077       // TODO(mlavan): check formatting for host and origin
   2078       buffer = altsvc_scratch_.host.get();
   2079       buffer_len = &altsvc_scratch_.host_buf_len;
   2080       bytes_remaining = altsvc_scratch_.host_len - altsvc_scratch_.host_buf_len;
   2081     } else {
   2082       // Buffer (optional) origin field as it comes in.
   2083       if (altsvc_scratch_.origin_len <= 0) {
   2084         set_error(SPDY_INVALID_CONTROL_FRAME);
   2085         return 0;
   2086       }
   2087       buffer = altsvc_scratch_.origin.get();
   2088       buffer_len = &altsvc_scratch_.origin_buf_len;
   2089       bytes_remaining = remaining_data_length_ -
   2090         processed_bytes -
   2091         altsvc_scratch_.origin_buf_len;
   2092       if (len > bytes_remaining) {
   2093         // This is our last field; there shouldn't be any more bytes.
   2094         set_error(SPDY_INVALID_CONTROL_FRAME);
   2095         return 0;
   2096       }
   2097     }
   2098 
   2099     // Copy data bytes into the appropriate field.
   2100     processing = std::min(len, bytes_remaining);
   2101     memcpy(buffer + *buffer_len,
   2102            data,
   2103            processing);
   2104     *buffer_len += processing;
   2105     data += processing;
   2106     processed_bytes += processing;
   2107     len -= processing;
   2108   }
   2109 
   2110   remaining_data_length_ -= processed_bytes;
   2111   if (remaining_data_length_ == 0) {
   2112     visitor_->OnAltSvc(current_frame_stream_id_,
   2113                        altsvc_scratch_.max_age,
   2114                        altsvc_scratch_.port,
   2115                        StringPiece(altsvc_scratch_.protocol_id.get(),
   2116                                    altsvc_scratch_.pid_len),
   2117                        StringPiece(altsvc_scratch_.host.get(),
   2118                                    altsvc_scratch_.host_len),
   2119                        StringPiece(altsvc_scratch_.origin.get(),
   2120                                    altsvc_scratch_.origin_len));
   2121     CHANGE_STATE(SPDY_AUTO_RESET);
   2122   }
   2123 
   2124   return processed_bytes;
   2125 }
   2126 
   2127 // TODO(raullenchai): ProcessFramePaddingLength should be able to deal with
   2128 // HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051).
   2129 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
   2130   DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
   2131   DCHECK_EQ(remaining_padding_payload_length_, 0u);
   2132 
   2133   size_t original_len = len;
   2134   if (current_frame_flags_ & DATA_FLAG_PADDED) {
   2135     if (len != 0) {
   2136       if (remaining_data_length_ < 1) {
   2137         set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
   2138         return 0;
   2139       }
   2140 
   2141       remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data);
   2142       ++data;
   2143       --len;
   2144       --remaining_data_length_;
   2145     } else {
   2146       // We don't have the data available for parsing the pad length field. Keep
   2147       // waiting.
   2148       return 0;
   2149     }
   2150   }
   2151 
   2152   if (remaining_padding_payload_length_ > remaining_data_length_) {
   2153     set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
   2154     return 0;
   2155   }
   2156   if (current_frame_type_ == DATA) {
   2157     CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
   2158   } else {
   2159     DCHECK(current_frame_type_ == HEADERS ||
   2160            current_frame_type_ == PUSH_PROMISE ||
   2161            current_frame_type_ == SYN_STREAM ||
   2162            current_frame_type_ == SYN_REPLY)
   2163         << current_frame_type_;
   2164     CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   2165   }
   2166   return original_len - len;
   2167 }
   2168 
   2169 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
   2170   DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
   2171 
   2172   size_t original_len = len;
   2173   if (remaining_padding_payload_length_ > 0) {
   2174     DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
   2175     size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
   2176     if (current_frame_type_ == DATA && amount_to_discard > 0) {
   2177       // The visitor needs to know about padding so it can send window updates.
   2178       // Communicate the padding to the visitor through a NULL data pointer,
   2179       // with a nonzero size.
   2180       visitor_->OnStreamFrameData(
   2181           current_frame_stream_id_, NULL, amount_to_discard, false);
   2182     }
   2183     data += amount_to_discard;
   2184     len -= amount_to_discard;
   2185     remaining_padding_payload_length_ -= amount_to_discard;
   2186     remaining_data_length_ -= amount_to_discard;
   2187   }
   2188 
   2189   if (remaining_data_length_ == 0) {
   2190     // If the FIN flag is set, or this ends a header block which set FIN,
   2191     // inform the visitor of EOF via a 0-length data frame.
   2192     if (expect_continuation_ == 0 &&
   2193         ((current_frame_flags_ & CONTROL_FLAG_FIN) != 0 ||
   2194          end_stream_when_done_)) {
   2195       end_stream_when_done_ = false;
   2196       visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
   2197     }
   2198     CHANGE_STATE(SPDY_AUTO_RESET);
   2199   }
   2200   return original_len - len;
   2201 }
   2202 
   2203 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
   2204   size_t original_len = len;
   2205   if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
   2206     size_t amount_to_forward = std::min(
   2207         remaining_data_length_ - remaining_padding_payload_length_, len);
   2208     if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
   2209       // Only inform the visitor if there is data.
   2210       if (amount_to_forward) {
   2211         visitor_->OnStreamFrameData(
   2212             current_frame_stream_id_, data, amount_to_forward, false);
   2213       }
   2214     }
   2215     data += amount_to_forward;
   2216     len -= amount_to_forward;
   2217     remaining_data_length_ -= amount_to_forward;
   2218   }
   2219 
   2220   if (remaining_data_length_ == remaining_padding_payload_length_) {
   2221     CHANGE_STATE(SPDY_CONSUME_PADDING);
   2222   }
   2223   return original_len - len;
   2224 }
   2225 
   2226 size_t SpdyFramer::ProcessIgnoredControlFramePayload(/*const char* data,*/
   2227                                                      size_t len) {
   2228   size_t original_len = len;
   2229   if (remaining_data_length_ > 0) {
   2230     size_t amount_to_ignore = std::min(remaining_data_length_, len);
   2231     len -= amount_to_ignore;
   2232     remaining_data_length_ -= amount_to_ignore;
   2233   }
   2234 
   2235   if (remaining_data_length_ == 0) {
   2236     CHANGE_STATE(SPDY_AUTO_RESET);
   2237   }
   2238   return original_len - len;
   2239 }
   2240 
   2241 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
   2242                                           size_t header_length,
   2243                                           SpdyHeaderBlock* block) const {
   2244   SpdyFrameReader reader(header_data, header_length);
   2245 
   2246   // Read number of headers.
   2247   uint32 num_headers;
   2248   if (protocol_version() <= SPDY2) {
   2249     uint16 temp;
   2250     if (!reader.ReadUInt16(&temp)) {
   2251       DVLOG(1) << "Unable to read number of headers.";
   2252       return 0;
   2253     }
   2254     num_headers = temp;
   2255   } else {
   2256     if (!reader.ReadUInt32(&num_headers)) {
   2257       DVLOG(1) << "Unable to read number of headers.";
   2258       return 0;
   2259     }
   2260   }
   2261 
   2262   // Read each header.
   2263   for (uint32 index = 0; index < num_headers; ++index) {
   2264     base::StringPiece temp;
   2265 
   2266     // Read header name.
   2267     if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
   2268                             : !reader.ReadStringPiece32(&temp)) {
   2269       DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
   2270                << num_headers << ").";
   2271       return 0;
   2272     }
   2273     std::string name = temp.as_string();
   2274 
   2275     // Read header value.
   2276     if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
   2277                             : !reader.ReadStringPiece32(&temp)) {
   2278       DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
   2279                << num_headers << ").";
   2280       return 0;
   2281     }
   2282     std::string value = temp.as_string();
   2283 
   2284     // Ensure no duplicates.
   2285     if (block->find(name) != block->end()) {
   2286       DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of "
   2287                << num_headers << ").";
   2288       return 0;
   2289     }
   2290 
   2291     // Store header.
   2292     (*block)[name] = value;
   2293   }
   2294   return reader.GetBytesConsumed();
   2295 }
   2296 
   2297 SpdySerializedFrame* SpdyFramer::SerializeData(
   2298     const SpdyDataIR& data_ir) const {
   2299   uint8 flags = DATA_FLAG_NONE;
   2300   if (data_ir.fin()) {
   2301     flags = DATA_FLAG_FIN;
   2302   }
   2303 
   2304   if (protocol_version() > SPDY3) {
   2305     int num_padding_fields = 0;
   2306     if (data_ir.padded()) {
   2307       flags |= DATA_FLAG_PADDED;
   2308       ++num_padding_fields;
   2309     }
   2310 
   2311     const size_t size_with_padding = num_padding_fields +
   2312         data_ir.data().length() + data_ir.padding_payload_len() +
   2313         GetDataFrameMinimumSize();
   2314     SpdyFrameBuilder builder(size_with_padding, protocol_version());
   2315     builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
   2316     if (data_ir.padded()) {
   2317       builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
   2318     }
   2319     builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
   2320     if (data_ir.padding_payload_len() > 0) {
   2321       string padding = string(data_ir.padding_payload_len(), '0');
   2322       builder.WriteBytes(padding.data(), padding.length());
   2323     }
   2324     DCHECK_EQ(size_with_padding, builder.length());
   2325     return builder.take();
   2326   } else {
   2327     const size_t size = GetDataFrameMinimumSize() + data_ir.data().length();
   2328     SpdyFrameBuilder builder(size, protocol_version());
   2329     builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
   2330     builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
   2331     DCHECK_EQ(size, builder.length());
   2332     return builder.take();
   2333   }
   2334 }
   2335 
   2336 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
   2337     const SpdyDataIR& data_ir) const {
   2338   uint8 flags = DATA_FLAG_NONE;
   2339   if (data_ir.fin()) {
   2340     flags = DATA_FLAG_FIN;
   2341   }
   2342 
   2343   size_t frame_size = GetDataFrameMinimumSize();
   2344   size_t num_padding_fields = 0;
   2345   if (protocol_version() > SPDY3) {
   2346     if (data_ir.padded()) {
   2347       flags |= DATA_FLAG_PADDED;
   2348       ++num_padding_fields;
   2349     }
   2350     frame_size += num_padding_fields;
   2351   }
   2352 
   2353   SpdyFrameBuilder builder(frame_size, protocol_version());
   2354   builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
   2355   if (protocol_version() > SPDY3) {
   2356     if (data_ir.padded()) {
   2357       builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
   2358     }
   2359     builder.OverwriteLength(*this,  num_padding_fields +
   2360         data_ir.data().length() + data_ir.padding_payload_len());
   2361   } else {
   2362     builder.OverwriteLength(*this, data_ir.data().length());
   2363   }
   2364   DCHECK_EQ(frame_size, builder.length());
   2365   return builder.take();
   2366 }
   2367 
   2368 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
   2369     const SpdySynStreamIR& syn_stream) {
   2370   DCHECK_GE(SPDY3, protocol_version());
   2371   uint8 flags = 0;
   2372   if (syn_stream.fin()) {
   2373     flags |= CONTROL_FLAG_FIN;
   2374   }
   2375   if (syn_stream.unidirectional()) {
   2376     // TODO(hkhalil): invalid for HTTP2.
   2377     flags |= CONTROL_FLAG_UNIDIRECTIONAL;
   2378   }
   2379 
   2380   // Sanitize priority.
   2381   uint8 priority = syn_stream.priority();
   2382   if (priority > GetLowestPriority()) {
   2383     DLOG(DFATAL) << "Priority out-of-bounds.";
   2384     priority = GetLowestPriority();
   2385   }
   2386 
   2387   // The size of this frame, including variable-length name-value block.
   2388   size_t size = GetSynStreamMinimumSize() +
   2389       GetSerializedLength(syn_stream.name_value_block());
   2390 
   2391   SpdyFrameBuilder builder(size, protocol_version());
   2392   builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
   2393   builder.WriteUInt32(syn_stream.stream_id());
   2394   builder.WriteUInt32(syn_stream.associated_to_stream_id());
   2395   builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
   2396   builder.WriteUInt8(0);  // Unused byte where credential slot used to be.
   2397   DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
   2398   SerializeNameValueBlock(&builder, syn_stream);
   2399 
   2400   if (debug_visitor_) {
   2401     const size_t payload_len =
   2402         GetSerializedLength(protocol_version(),
   2403                             &(syn_stream.name_value_block()));
   2404     debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
   2405                                           SYN_STREAM,
   2406                                           payload_len,
   2407                                           builder.length());
   2408   }
   2409 
   2410   return builder.take();
   2411 }
   2412 
   2413 SpdySerializedFrame* SpdyFramer::SerializeSynReply(
   2414     const SpdySynReplyIR& syn_reply) {
   2415   DCHECK_GE(SPDY3, protocol_version());
   2416   uint8 flags = 0;
   2417   if (syn_reply.fin()) {
   2418     flags |= CONTROL_FLAG_FIN;
   2419   }
   2420 
   2421   // The size of this frame, including variable-length name-value block.
   2422   const size_t size = GetSynReplyMinimumSize() +
   2423                       GetSerializedLength(syn_reply.name_value_block());
   2424 
   2425   SpdyFrameBuilder builder(size, protocol_version());
   2426   if (protocol_version() <= SPDY3) {
   2427     builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
   2428     builder.WriteUInt32(syn_reply.stream_id());
   2429   } else {
   2430     builder.BeginNewFrame(*this,
   2431                           HEADERS,
   2432                           flags,
   2433                           syn_reply.stream_id());
   2434   }
   2435   if (protocol_version() < SPDY3) {
   2436     builder.WriteUInt16(0);  // Unused.
   2437   }
   2438   DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
   2439   SerializeNameValueBlock(&builder, syn_reply);
   2440 
   2441   if (debug_visitor_) {
   2442     const size_t payload_len = GetSerializedLength(
   2443         protocol_version(), &(syn_reply.name_value_block()));
   2444     debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
   2445                                           SYN_REPLY,
   2446                                           payload_len,
   2447                                           builder.length());
   2448   }
   2449 
   2450   return builder.take();
   2451 }
   2452 
   2453 SpdySerializedFrame* SpdyFramer::SerializeRstStream(
   2454     const SpdyRstStreamIR& rst_stream) const {
   2455   // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
   2456   // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
   2457   // which doesn't currently include RST_STREAM payloads. GFE flags have been
   2458   // commented but left in place to simplify future patching.
   2459   // Compute the output buffer size, taking opaque data into account.
   2460   uint16 expected_length = GetRstStreamMinimumSize();
   2461   if (protocol_version() > SPDY3) {
   2462     expected_length += rst_stream.description().size();
   2463   }
   2464   SpdyFrameBuilder builder(expected_length, protocol_version());
   2465 
   2466   // Serialize the RST_STREAM frame.
   2467   if (protocol_version() <= SPDY3) {
   2468     builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
   2469     builder.WriteUInt32(rst_stream.stream_id());
   2470   } else {
   2471     builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
   2472   }
   2473 
   2474   builder.WriteUInt32(rst_stream.status());
   2475 
   2476   // In SPDY4 and up, RST_STREAM frames may also specify opaque data.
   2477   if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
   2478     builder.WriteBytes(rst_stream.description().data(),
   2479                        rst_stream.description().size());
   2480   }
   2481 
   2482   DCHECK_EQ(expected_length, builder.length());
   2483   return builder.take();
   2484 }
   2485 
   2486 SpdySerializedFrame* SpdyFramer::SerializeSettings(
   2487     const SpdySettingsIR& settings) const {
   2488   uint8 flags = 0;
   2489 
   2490   if (protocol_version() <= SPDY3) {
   2491     if (settings.clear_settings()) {
   2492       flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
   2493     }
   2494   } else {
   2495     if (settings.is_ack()) {
   2496       flags |= SETTINGS_FLAG_ACK;
   2497     }
   2498   }
   2499   const SpdySettingsIR::ValueMap* values = &(settings.values());
   2500 
   2501   size_t setting_size = SpdyConstants::GetSettingSize(protocol_version());
   2502   // Size, in bytes, of this SETTINGS frame.
   2503   const size_t size = GetSettingsMinimumSize() +
   2504                       (values->size() * setting_size);
   2505   SpdyFrameBuilder builder(size, protocol_version());
   2506   if (protocol_version() <= SPDY3) {
   2507     builder.WriteControlFrameHeader(*this, SETTINGS, flags);
   2508   } else {
   2509     builder.BeginNewFrame(*this, SETTINGS, flags, 0);
   2510   }
   2511 
   2512   // If this is an ACK, payload should be empty.
   2513   if (protocol_version() > SPDY3 && settings.is_ack()) {
   2514     return builder.take();
   2515   }
   2516 
   2517   if (protocol_version() <= SPDY3) {
   2518     builder.WriteUInt32(values->size());
   2519   }
   2520   DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
   2521   for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
   2522        it != values->end();
   2523        ++it) {
   2524     if (protocol_version() <= SPDY3) {
   2525       uint8 setting_flags = 0;
   2526       if (it->second.persist_value) {
   2527         setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
   2528       }
   2529       if (it->second.persisted) {
   2530         setting_flags |= SETTINGS_FLAG_PERSISTED;
   2531       }
   2532       SettingsFlagsAndId flags_and_id(
   2533           setting_flags,
   2534           SpdyConstants::SerializeSettingId(protocol_version(), it->first));
   2535       uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
   2536       builder.WriteBytes(&id_and_flags_wire, 4);
   2537     } else {
   2538       builder.WriteUInt16(SpdyConstants::SerializeSettingId(protocol_version(),
   2539                                                             it->first));
   2540     }
   2541     builder.WriteUInt32(it->second.value);
   2542   }
   2543   DCHECK_EQ(size, builder.length());
   2544   return builder.take();
   2545 }
   2546 
   2547 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
   2548   SpdyFrameBuilder builder(GetPingSize(), protocol_version());
   2549   if (protocol_version() <= SPDY3) {
   2550     builder.WriteControlFrameHeader(*this, PING, kNoFlags);
   2551     builder.WriteUInt32(static_cast<uint32>(ping.id()));
   2552   } else {
   2553     uint8 flags = 0;
   2554     if (ping.is_ack()) {
   2555       flags |= PING_FLAG_ACK;
   2556     }
   2557     builder.BeginNewFrame(*this, PING, flags, 0);
   2558     builder.WriteUInt64(ping.id());
   2559   }
   2560   DCHECK_EQ(GetPingSize(), builder.length());
   2561   return builder.take();
   2562 }
   2563 
   2564 SpdySerializedFrame* SpdyFramer::SerializeGoAway(
   2565     const SpdyGoAwayIR& goaway) const {
   2566 
   2567   // Compute the output buffer size, take opaque data into account.
   2568   uint16 expected_length = GetGoAwayMinimumSize();
   2569   if (protocol_version() > SPDY3) {
   2570     expected_length += goaway.description().size();
   2571   }
   2572   SpdyFrameBuilder builder(expected_length, protocol_version());
   2573 
   2574   // Serialize the GOAWAY frame.
   2575   if (protocol_version() <= SPDY3) {
   2576     builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
   2577   } else {
   2578     builder.BeginNewFrame(*this, GOAWAY, 0, 0);
   2579   }
   2580 
   2581   // GOAWAY frames specify the last good stream id for all SPDY versions.
   2582   builder.WriteUInt32(goaway.last_good_stream_id());
   2583 
   2584   // In SPDY3 and up, GOAWAY frames also specify the error status code.
   2585   if (protocol_version() >= SPDY3) {
   2586     // TODO(jgraettinger): Merge back to server-side.
   2587     builder.WriteUInt32(SpdyConstants::SerializeGoAwayStatus(protocol_version(),
   2588                                                              goaway.status()));
   2589   }
   2590 
   2591   // In SPDY4 and up, GOAWAY frames may also specify opaque data.
   2592   if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) {
   2593     builder.WriteBytes(goaway.description().data(),
   2594                        goaway.description().size());
   2595   }
   2596 
   2597   DCHECK_EQ(expected_length, builder.length());
   2598   return builder.take();
   2599 }
   2600 
   2601 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
   2602     const SpdyHeadersIR& headers) {
   2603   uint8 flags = 0;
   2604   if (headers.fin()) {
   2605     flags |= CONTROL_FLAG_FIN;
   2606   }
   2607   if (protocol_version() > SPDY3) {
   2608     // This will get overwritten if we overflow into a CONTINUATION frame.
   2609     flags |= HEADERS_FLAG_END_HEADERS;
   2610     if (headers.has_priority()) {
   2611       flags |= HEADERS_FLAG_PRIORITY;
   2612     }
   2613   }
   2614 
   2615   // The size of this frame, including variable-length name-value block.
   2616   size_t size = GetHeadersMinimumSize();
   2617 
   2618   uint32 priority = headers.priority();
   2619   if (headers.has_priority()) {
   2620     if (priority > GetLowestPriority()) {
   2621       DLOG(DFATAL) << "Priority out-of-bounds.";
   2622       priority = GetLowestPriority();
   2623     }
   2624     size += 5;
   2625   }
   2626 
   2627   string hpack_encoding;
   2628   if (protocol_version() > SPDY3) {
   2629     if (enable_compression_) {
   2630       GetHpackEncoder()->EncodeHeaderSet(
   2631           headers.name_value_block(), &hpack_encoding);
   2632     } else {
   2633       GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
   2634           headers.name_value_block(), &hpack_encoding);
   2635     }
   2636     size += hpack_encoding.size();
   2637     if (size > GetHeaderFragmentMaxSize()) {
   2638       size += GetNumberRequiredContinuationFrames(size) *
   2639               GetContinuationMinimumSize();
   2640       flags &= ~HEADERS_FLAG_END_HEADERS;
   2641     }
   2642   } else {
   2643     size += GetSerializedLength(headers.name_value_block());
   2644   }
   2645 
   2646   SpdyFrameBuilder builder(size, protocol_version());
   2647   if (protocol_version() <= SPDY3) {
   2648     builder.WriteControlFrameHeader(*this, HEADERS, flags);
   2649     builder.WriteUInt32(headers.stream_id());
   2650   } else {
   2651     builder.BeginNewFrame(*this,
   2652                           HEADERS,
   2653                           flags,
   2654                           headers.stream_id());
   2655   }
   2656   if (protocol_version() <= SPDY2) {
   2657     builder.WriteUInt16(0);  // Unused.
   2658   }
   2659   DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
   2660 
   2661   if (protocol_version() > SPDY3) {
   2662     if (headers.has_priority()) {
   2663       // TODO(jgraettinger): Plumb priorities and stream dependencies.
   2664       builder.WriteUInt32(0);  // Non-exclusive bit and root stream ID.
   2665       builder.WriteUInt8(MapPriorityToWeight(priority));
   2666     }
   2667     WritePayloadWithContinuation(&builder,
   2668                                  hpack_encoding,
   2669                                  headers.stream_id(),
   2670                                  HEADERS);
   2671   } else {
   2672     SerializeNameValueBlock(&builder, headers);
   2673   }
   2674 
   2675   if (debug_visitor_) {
   2676     // SPDY4 uses HPACK for header compression. However, continue to
   2677     // use GetSerializedLength() for an apples-to-apples comparision of
   2678     // compression performance between HPACK and SPDY w/ deflate.
   2679     const size_t payload_len =
   2680         GetSerializedLength(protocol_version(),
   2681                             &(headers.name_value_block()));
   2682     debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
   2683                                           HEADERS,
   2684                                           payload_len,
   2685                                           builder.length());
   2686   }
   2687 
   2688   return builder.take();
   2689 }
   2690 
   2691 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
   2692     const SpdyWindowUpdateIR& window_update) const {
   2693   SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version());
   2694   if (protocol_version() <= SPDY3) {
   2695     builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
   2696     builder.WriteUInt32(window_update.stream_id());
   2697   } else {
   2698     builder.BeginNewFrame(*this,
   2699                           WINDOW_UPDATE,
   2700                           kNoFlags,
   2701                           window_update.stream_id());
   2702   }
   2703   builder.WriteUInt32(window_update.delta());
   2704   DCHECK_EQ(GetWindowUpdateSize(), builder.length());
   2705   return builder.take();
   2706 }
   2707 
   2708 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
   2709   DCHECK_LT(SPDY3, protocol_version());
   2710   SpdyFrameBuilder builder(GetBlockedSize(), protocol_version());
   2711   builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
   2712   return builder.take();
   2713 }
   2714 
   2715 SpdyFrame* SpdyFramer::SerializePushPromise(
   2716     const SpdyPushPromiseIR& push_promise) {
   2717   DCHECK_LT(SPDY3, protocol_version());
   2718   uint8 flags = 0;
   2719   // This will get overwritten if we overflow into a CONTINUATION frame.
   2720   flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
   2721   // The size of this frame, including variable-length name-value block.
   2722   size_t size = GetPushPromiseMinimumSize();
   2723 
   2724   string hpack_encoding;
   2725   if (enable_compression_) {
   2726     GetHpackEncoder()->EncodeHeaderSet(
   2727         push_promise.name_value_block(), &hpack_encoding);
   2728   } else {
   2729     GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
   2730         push_promise.name_value_block(), &hpack_encoding);
   2731   }
   2732   size += hpack_encoding.size();
   2733   if (size > GetHeaderFragmentMaxSize()) {
   2734     size += GetNumberRequiredContinuationFrames(size) *
   2735             GetContinuationMinimumSize();
   2736     flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
   2737   }
   2738 
   2739   SpdyFrameBuilder builder(size, protocol_version());
   2740   builder.BeginNewFrame(*this,
   2741                         PUSH_PROMISE,
   2742                         flags,
   2743                         push_promise.stream_id());
   2744   builder.WriteUInt32(push_promise.promised_stream_id());
   2745   DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
   2746 
   2747   WritePayloadWithContinuation(&builder,
   2748                                hpack_encoding,
   2749                                push_promise.stream_id(),
   2750                                PUSH_PROMISE);
   2751 
   2752   if (debug_visitor_) {
   2753     // SPDY4 uses HPACK for header compression. However, continue to
   2754     // use GetSerializedLength() for an apples-to-apples comparision of
   2755     // compression performance between HPACK and SPDY w/ deflate.
   2756     const size_t payload_len =
   2757         GetSerializedLength(protocol_version(),
   2758                             &(push_promise.name_value_block()));
   2759     debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
   2760                                           PUSH_PROMISE,
   2761                                           payload_len,
   2762                                           builder.length());
   2763   }
   2764 
   2765   return builder.take();
   2766 }
   2767 
   2768 // TODO(jgraettinger): This implementation is incorrect. The continuation
   2769 // frame continues a previously-begun HPACK encoding; it doesn't begin a
   2770 // new one. Figure out whether it makes sense to keep SerializeContinuation().
   2771 SpdyFrame* SpdyFramer::SerializeContinuation(
   2772     const SpdyContinuationIR& continuation) {
   2773   CHECK_LT(SPDY3, protocol_version());
   2774   uint8 flags = 0;
   2775   if (continuation.end_headers()) {
   2776     flags |= HEADERS_FLAG_END_HEADERS;
   2777   }
   2778 
   2779   // The size of this frame, including variable-length name-value block.
   2780   size_t size = GetContinuationMinimumSize();
   2781   string hpack_encoding;
   2782   if (enable_compression_) {
   2783     GetHpackEncoder()->EncodeHeaderSet(
   2784         continuation.name_value_block(), &hpack_encoding);
   2785   } else {
   2786     GetHpackEncoder()->EncodeHeaderSetWithoutCompression(
   2787         continuation.name_value_block(), &hpack_encoding);
   2788   }
   2789   size += hpack_encoding.size();
   2790 
   2791   SpdyFrameBuilder builder(size, protocol_version());
   2792   builder.BeginNewFrame(*this, CONTINUATION, flags,
   2793       continuation.stream_id());
   2794   DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
   2795 
   2796   builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
   2797   return builder.take();
   2798 }
   2799 
   2800 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) {
   2801   DCHECK_LT(SPDY3, protocol_version());
   2802   size_t size = GetAltSvcMinimumSize();
   2803   size += altsvc.protocol_id().length();
   2804   size += altsvc.host().length();
   2805   size += altsvc.origin().length();
   2806 
   2807   SpdyFrameBuilder builder(size, protocol_version());
   2808   builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id());
   2809 
   2810   builder.WriteUInt32(altsvc.max_age());
   2811   builder.WriteUInt16(altsvc.port());
   2812   builder.WriteUInt8(0);  // Reserved.
   2813   builder.WriteUInt8(altsvc.protocol_id().length());
   2814   builder.WriteBytes(altsvc.protocol_id().data(),
   2815                      altsvc.protocol_id().length());
   2816   builder.WriteUInt8(altsvc.host().length());
   2817   builder.WriteBytes(altsvc.host().data(), altsvc.host().length());
   2818   builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length());
   2819   DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
   2820   return builder.take();
   2821 }
   2822 
   2823 SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) {
   2824   DCHECK_LT(SPDY3, protocol_version());
   2825   size_t size = GetPrioritySize();
   2826 
   2827   SpdyFrameBuilder builder(size, protocol_version());
   2828   builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id());
   2829 
   2830   // Make sure the highest-order bit in the parent stream id is zeroed out.
   2831   uint32 parent_stream_id = priority.parent_stream_id() & 0x7fffffff;
   2832   uint32 exclusive = priority.exclusive() ? 0x80000000 : 0;
   2833   // Set the one-bit exclusivity flag.
   2834   uint32 flag_and_parent_id = parent_stream_id | exclusive;
   2835   builder.WriteUInt32(flag_and_parent_id);
   2836   builder.WriteUInt8(priority.weight());
   2837   DCHECK_EQ(GetPrioritySize(), builder.length());
   2838   return builder.take();
   2839 }
   2840 
   2841 namespace {
   2842 
   2843 class FrameSerializationVisitor : public SpdyFrameVisitor {
   2844  public:
   2845   explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
   2846   virtual ~FrameSerializationVisitor() {}
   2847 
   2848   SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
   2849 
   2850   virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
   2851     frame_.reset(framer_->SerializeData(data));
   2852   }
   2853   virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE {
   2854     frame_.reset(framer_->SerializeSynStream(syn_stream));
   2855   }
   2856   virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE {
   2857     frame_.reset(framer_->SerializeSynReply(syn_reply));
   2858   }
   2859   virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE {
   2860     frame_.reset(framer_->SerializeRstStream(rst_stream));
   2861   }
   2862   virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE {
   2863     frame_.reset(framer_->SerializeSettings(settings));
   2864   }
   2865   virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE {
   2866     frame_.reset(framer_->SerializePing(ping));
   2867   }
   2868   virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE {
   2869     frame_.reset(framer_->SerializeGoAway(goaway));
   2870   }
   2871   virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE {
   2872     frame_.reset(framer_->SerializeHeaders(headers));
   2873   }
   2874   virtual void VisitWindowUpdate(
   2875       const SpdyWindowUpdateIR& window_update) OVERRIDE {
   2876     frame_.reset(framer_->SerializeWindowUpdate(window_update));
   2877   }
   2878   virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE {
   2879     frame_.reset(framer_->SerializeBlocked(blocked));
   2880   }
   2881   virtual void VisitPushPromise(
   2882       const SpdyPushPromiseIR& push_promise) OVERRIDE {
   2883     frame_.reset(framer_->SerializePushPromise(push_promise));
   2884   }
   2885   virtual void VisitContinuation(
   2886       const SpdyContinuationIR& continuation) OVERRIDE {
   2887     frame_.reset(framer_->SerializeContinuation(continuation));
   2888   }
   2889   virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE {
   2890     frame_.reset(framer_->SerializeAltSvc(altsvc));
   2891   }
   2892   virtual void VisitPriority(const SpdyPriorityIR& priority) OVERRIDE {
   2893     frame_.reset(framer_->SerializePriority(priority));
   2894   }
   2895 
   2896  private:
   2897   SpdyFramer* framer_;
   2898   scoped_ptr<SpdySerializedFrame> frame_;
   2899 };
   2900 
   2901 }  // namespace
   2902 
   2903 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
   2904   FrameSerializationVisitor visitor(this);
   2905   frame.Visit(&visitor);
   2906   return visitor.ReleaseSerializedFrame();
   2907 }
   2908 
   2909 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
   2910   CHECK_GE(SPDY3, protocol_version());
   2911   const size_t uncompressed_length =
   2912     GetSerializedLength(protocol_version(), &headers);
   2913   if (!enable_compression_) {
   2914     return uncompressed_length;
   2915   }
   2916   z_stream* compressor = GetHeaderCompressor();
   2917   // Since we'll be performing lots of flushes when compressing the data,
   2918   // zlib's lower bounds may be insufficient.
   2919   return 2 * deflateBound(compressor, uncompressed_length);
   2920 }
   2921 
   2922 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
   2923   const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
   2924   DCHECK_GT(protocol_version(), SPDY3);
   2925   DCHECK_GT(size, kMaxControlFrameSize);
   2926   size_t overflow = size - kMaxControlFrameSize;
   2927   return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
   2928 }
   2929 
   2930 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
   2931                                               const string& hpack_encoding,
   2932                                               SpdyStreamId stream_id,
   2933                                               SpdyFrameType type) {
   2934   const size_t kMaxControlFrameSize = GetHeaderFragmentMaxSize();
   2935 
   2936     // In addition to the prefix, fixed_field_size includes the size of
   2937     // any fields that come before the variable-length name/value block.
   2938     size_t fixed_field_size = 0;
   2939     uint8 end_flag = 0;
   2940     uint8 flags = 0;
   2941     if (type == HEADERS) {
   2942       fixed_field_size = GetHeadersMinimumSize();
   2943       end_flag = HEADERS_FLAG_END_HEADERS;
   2944     } else if (type == PUSH_PROMISE) {
   2945       fixed_field_size = GetPushPromiseMinimumSize();
   2946       end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
   2947     } else {
   2948       DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
   2949                   << FrameTypeToString(type);
   2950     }
   2951 
   2952     // Write as much of the payload as possible into the initial frame.
   2953     size_t bytes_remaining = hpack_encoding.size() -
   2954         std::min(hpack_encoding.size(),
   2955                  kMaxControlFrameSize - fixed_field_size);
   2956     builder->WriteBytes(&hpack_encoding[0],
   2957                         hpack_encoding.size() - bytes_remaining);
   2958 
   2959     if (bytes_remaining > 0) {
   2960       builder->OverwriteLength(*this,
   2961           kMaxControlFrameSize - GetControlFrameHeaderSize());
   2962     }
   2963 
   2964     // Tack on CONTINUATION frames for the overflow.
   2965     while (bytes_remaining > 0) {
   2966       size_t bytes_to_write = std::min(bytes_remaining,
   2967                                        kMaxControlFrameSize -
   2968                                        GetContinuationMinimumSize());
   2969       // Write CONTINUATION frame prefix.
   2970       if (bytes_remaining == bytes_to_write) {
   2971         flags |= end_flag;
   2972       }
   2973       builder->BeginNewFrame(*this,
   2974                              CONTINUATION,
   2975                              flags,
   2976                              stream_id);
   2977       // Write payload fragment.
   2978       builder->WriteBytes(&hpack_encoding[hpack_encoding.size() -
   2979                                           bytes_remaining],
   2980                           bytes_to_write);
   2981       bytes_remaining -= bytes_to_write;
   2982     }
   2983 }
   2984 
   2985 // The following compression setting are based on Brian Olson's analysis. See
   2986 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
   2987 // for more details.
   2988 #if defined(USE_SYSTEM_ZLIB)
   2989 // System zlib is not expected to have workaround for http://crbug.com/139744,
   2990 // so disable compression in that case.
   2991 // TODO(phajdan.jr): Remove the special case when it's no longer necessary.
   2992 static const int kCompressorLevel = 0;
   2993 #else  // !defined(USE_SYSTEM_ZLIB)
   2994 static const int kCompressorLevel = 9;
   2995 #endif  // !defined(USE_SYSTEM_ZLIB)
   2996 static const int kCompressorWindowSizeInBits = 11;
   2997 static const int kCompressorMemLevel = 1;
   2998 
   2999 z_stream* SpdyFramer::GetHeaderCompressor() {
   3000   if (header_compressor_.get())
   3001     return header_compressor_.get();  // Already initialized.
   3002 
   3003   header_compressor_.reset(new z_stream);
   3004   memset(header_compressor_.get(), 0, sizeof(z_stream));
   3005 
   3006   int success = deflateInit2(header_compressor_.get(),
   3007                              kCompressorLevel,
   3008                              Z_DEFLATED,
   3009                              kCompressorWindowSizeInBits,
   3010                              kCompressorMemLevel,
   3011                              Z_DEFAULT_STRATEGY);
   3012   if (success == Z_OK) {
   3013     const char* dictionary = (protocol_version() <= SPDY2) ?
   3014         kV2Dictionary : kV3Dictionary;
   3015     const int dictionary_size = (protocol_version() <= SPDY2) ?
   3016         kV2DictionarySize : kV3DictionarySize;
   3017     success = deflateSetDictionary(header_compressor_.get(),
   3018                                    reinterpret_cast<const Bytef*>(dictionary),
   3019                                    dictionary_size);
   3020   }
   3021   if (success != Z_OK) {
   3022     LOG(WARNING) << "deflateSetDictionary failure: " << success;
   3023     header_compressor_.reset(NULL);
   3024     return NULL;
   3025   }
   3026   return header_compressor_.get();
   3027 }
   3028 
   3029 z_stream* SpdyFramer::GetHeaderDecompressor() {
   3030   if (header_decompressor_.get())
   3031     return header_decompressor_.get();  // Already initialized.
   3032 
   3033   header_decompressor_.reset(new z_stream);
   3034   memset(header_decompressor_.get(), 0, sizeof(z_stream));
   3035 
   3036   int success = inflateInit(header_decompressor_.get());
   3037   if (success != Z_OK) {
   3038     LOG(WARNING) << "inflateInit failure: " << success;
   3039     header_decompressor_.reset(NULL);
   3040     return NULL;
   3041   }
   3042   return header_decompressor_.get();
   3043 }
   3044 
   3045 HpackEncoder* SpdyFramer::GetHpackEncoder() {
   3046   DCHECK_LT(SPDY3, spdy_version_);
   3047   if (hpack_encoder_.get() == NULL) {
   3048     hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
   3049   }
   3050   return hpack_encoder_.get();
   3051 }
   3052 
   3053 HpackDecoder* SpdyFramer::GetHpackDecoder() {
   3054   DCHECK_LT(SPDY3, spdy_version_);
   3055   if (hpack_decoder_.get() == NULL) {
   3056     hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
   3057   }
   3058   return hpack_decoder_.get();
   3059 }
   3060 
   3061 uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
   3062   const float kSteps = 255.9f / 7.f;
   3063   return static_cast<uint8>(kSteps * (7.f - priority));
   3064 }
   3065 
   3066 SpdyPriority SpdyFramer::MapWeightToPriority(uint8 weight) {
   3067   const float kSteps = 255.9f / 7.f;
   3068   return static_cast<SpdyPriority>(7.f - weight / kSteps);
   3069 }
   3070 
   3071 // Incrementally decompress the control frame's header block, feeding the
   3072 // result to the visitor in chunks. Continue this until the visitor
   3073 // indicates that it cannot process any more data, or (more commonly) we
   3074 // run out of data to deliver.
   3075 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
   3076     SpdyStreamId stream_id,
   3077     const char* data,
   3078     size_t len) {
   3079   // Get a decompressor or set error.
   3080   z_stream* decomp = GetHeaderDecompressor();
   3081   if (decomp == NULL) {
   3082     LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
   3083     set_error(SPDY_DECOMPRESS_FAILURE);
   3084     return false;
   3085   }
   3086 
   3087   bool processed_successfully = true;
   3088   char buffer[kHeaderDataChunkMaxSize];
   3089 
   3090   decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
   3091   decomp->avail_in = len;
   3092   // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we
   3093   // signal an error back in ProcessControlFrameBeforeHeaderBlock.  So if we've
   3094   // reached this method successfully, stream_id should be nonzero.
   3095   DCHECK_LT(0u, stream_id);
   3096   while (decomp->avail_in > 0 && processed_successfully) {
   3097     decomp->next_out = reinterpret_cast<Bytef*>(buffer);
   3098     decomp->avail_out = arraysize(buffer);
   3099 
   3100     int rv = inflate(decomp, Z_SYNC_FLUSH);
   3101     if (rv == Z_NEED_DICT) {
   3102       const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary
   3103                                                              : kV3Dictionary;
   3104       const int dictionary_size = (protocol_version() <= SPDY2) ?
   3105           kV2DictionarySize : kV3DictionarySize;
   3106       const DictionaryIds& ids = g_dictionary_ids.Get();
   3107       const uLong dictionary_id = (protocol_version() <= SPDY2) ?
   3108           ids.v2_dictionary_id : ids.v3_dictionary_id;
   3109       // Need to try again with the right dictionary.
   3110       if (decomp->adler == dictionary_id) {
   3111         rv = inflateSetDictionary(decomp,
   3112                                   reinterpret_cast<const Bytef*>(dictionary),
   3113                                   dictionary_size);
   3114         if (rv == Z_OK)
   3115           rv = inflate(decomp, Z_SYNC_FLUSH);
   3116       }
   3117     }
   3118 
   3119     // Inflate will generate a Z_BUF_ERROR if it runs out of input
   3120     // without producing any output.  The input is consumed and
   3121     // buffered internally by zlib so we can detect this condition by
   3122     // checking if avail_in is 0 after the call to inflate.
   3123     bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
   3124     if ((rv == Z_OK) || input_exhausted) {
   3125       size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
   3126       if (decompressed_len > 0) {
   3127         processed_successfully = visitor_->OnControlFrameHeaderData(
   3128             stream_id, buffer, decompressed_len);
   3129       }
   3130       if (!processed_successfully) {
   3131         // Assume that the problem was the header block was too large for the
   3132         // visitor.
   3133         set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   3134       }
   3135     } else {
   3136       DLOG(WARNING) << "inflate failure: " << rv << " " << len;
   3137       set_error(SPDY_DECOMPRESS_FAILURE);
   3138       processed_successfully = false;
   3139     }
   3140   }
   3141   return processed_successfully;
   3142 }
   3143 
   3144 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
   3145     SpdyStreamId stream_id, const char* data, size_t len) {
   3146   bool read_successfully = true;
   3147   while (read_successfully && len > 0) {
   3148     size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
   3149     read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
   3150                                                            bytes_to_deliver);
   3151     data += bytes_to_deliver;
   3152     len -= bytes_to_deliver;
   3153     if (!read_successfully) {
   3154       // Assume that the problem was the header block was too large for the
   3155       // visitor.
   3156       set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   3157     }
   3158   }
   3159   return read_successfully;
   3160 }
   3161 
   3162 void SpdyFramer::SerializeNameValueBlockWithoutCompression(
   3163     SpdyFrameBuilder* builder,
   3164     const SpdyNameValueBlock& name_value_block) const {
   3165   // Serialize number of headers.
   3166   if (protocol_version() <= SPDY2) {
   3167     builder->WriteUInt16(name_value_block.size());
   3168   } else {
   3169     builder->WriteUInt32(name_value_block.size());
   3170   }
   3171 
   3172   // Serialize each header.
   3173   for (SpdyHeaderBlock::const_iterator it = name_value_block.begin();
   3174        it != name_value_block.end();
   3175        ++it) {
   3176     if (protocol_version() <= SPDY2) {
   3177       builder->WriteString(it->first);
   3178       builder->WriteString(it->second);
   3179     } else {
   3180       builder->WriteStringPiece32(it->first);
   3181       builder->WriteStringPiece32(it->second);
   3182     }
   3183   }
   3184 }
   3185 
   3186 void SpdyFramer::SerializeNameValueBlock(
   3187     SpdyFrameBuilder* builder,
   3188     const SpdyFrameWithNameValueBlockIR& frame) {
   3189   CHECK_GE(SPDY3, protocol_version());
   3190   if (!enable_compression_) {
   3191     return SerializeNameValueBlockWithoutCompression(builder,
   3192                                                      frame.name_value_block());
   3193   }
   3194 
   3195   // First build an uncompressed version to be fed into the compressor.
   3196   const size_t uncompressed_len = GetSerializedLength(
   3197       protocol_version(), &(frame.name_value_block()));
   3198   SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version());
   3199   SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
   3200                                             frame.name_value_block());
   3201   scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());
   3202 
   3203   z_stream* compressor = GetHeaderCompressor();
   3204   if (!compressor) {
   3205     LOG(DFATAL) << "Could not obtain compressor.";
   3206     return;
   3207   }
   3208 
   3209   base::StatsCounter compressed_frames("spdy.CompressedFrames");
   3210   base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
   3211   base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
   3212 
   3213   // Create an output frame.
   3214   // Since we'll be performing lots of flushes when compressing the data,
   3215   // zlib's lower bounds may be insufficient.
   3216   //
   3217   // TODO(akalin): Avoid the duplicate calculation with
   3218   // GetSerializedLength(const SpdyHeaderBlock&).
   3219   const int compressed_max_size =
   3220       2 * deflateBound(compressor, uncompressed_len);
   3221 
   3222   // TODO(phajdan.jr): Clean up after we no longer need
   3223   // to workaround http://crbug.com/139744.
   3224 #if defined(USE_SYSTEM_ZLIB)
   3225   compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data());
   3226   compressor->avail_in = uncompressed_len;
   3227 #endif  // defined(USE_SYSTEM_ZLIB)
   3228   compressor->next_out = reinterpret_cast<Bytef*>(
   3229       builder->GetWritableBuffer(compressed_max_size));
   3230   compressor->avail_out = compressed_max_size;
   3231 
   3232   // TODO(phajdan.jr): Clean up after we no longer need
   3233   // to workaround http://crbug.com/139744.
   3234 #if defined(USE_SYSTEM_ZLIB)
   3235   int rv = deflate(compressor, Z_SYNC_FLUSH);
   3236   if (rv != Z_OK) {  // How can we know that it compressed everything?
   3237     // This shouldn't happen, right?
   3238     LOG(WARNING) << "deflate failure: " << rv;
   3239     // TODO(akalin): Upstream this return.
   3240     return;
   3241   }
   3242 #else
   3243   WriteHeaderBlockToZ(&frame.name_value_block(), compressor);
   3244 #endif  // defined(USE_SYSTEM_ZLIB)
   3245 
   3246   int compressed_size = compressed_max_size - compressor->avail_out;
   3247   builder->Seek(compressed_size);
   3248   builder->RewriteLength(*this);
   3249 
   3250   pre_compress_bytes.Add(uncompressed_len);
   3251   post_compress_bytes.Add(compressed_size);
   3252 
   3253   compressed_frames.Increment();
   3254 }
   3255 
   3256 }  // namespace net
   3257