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