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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't
      6 // constantly adding and subtracting header sizes; this is ugly and error-
      7 // prone.
      8 
      9 #include "net/spdy/spdy_framer.h"
     10 
     11 #include "base/lazy_instance.h"
     12 #include "base/memory/scoped_ptr.h"
     13 #include "base/metrics/stats_counters.h"
     14 #include "base/third_party/valgrind/memcheck.h"
     15 #include "net/spdy/spdy_frame_builder.h"
     16 #include "net/spdy/spdy_frame_reader.h"
     17 #include "net/spdy/spdy_bitmasks.h"
     18 #include "third_party/zlib/zlib.h"
     19 
     20 using std::vector;
     21 
     22 namespace net {
     23 
     24 namespace {
     25 
     26 // Compute the id of our dictionary so that we know we're using the
     27 // right one when asked for it.
     28 uLong CalculateDictionaryId(const char* dictionary,
     29                             const size_t dictionary_size) {
     30   uLong initial_value = adler32(0L, Z_NULL, 0);
     31   return adler32(initial_value,
     32                  reinterpret_cast<const Bytef*>(dictionary),
     33                  dictionary_size);
     34 }
     35 
     36 struct DictionaryIds {
     37   DictionaryIds()
     38     : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
     39       v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
     40   {}
     41   const uLong v2_dictionary_id;
     42   const uLong v3_dictionary_id;
     43 };
     44 
     45 // Adler ID for the SPDY header compressor dictionaries. Note that they are
     46 // initialized lazily to avoid static initializers.
     47 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
     48 
     49 // Used to indicate no flags in a SPDY flags field.
     50 const uint8 kNoFlags = 0;
     51 
     52 }  // namespace
     53 
     54 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
     55 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
     56 // The size of the control frame buffer. Must be >= the minimum size of the
     57 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
     58 // calculation details.
     59 const size_t SpdyFramer::kControlFrameBufferSize = 18;
     60 
     61 #ifdef DEBUG_SPDY_STATE_CHANGES
     62 #define CHANGE_STATE(newstate)                                  \
     63   do {                                                          \
     64     LOG(INFO) << "Changing state from: "                        \
     65               << StateToString(state_)                          \
     66               << " to " << StateToString(newstate) << "\n";     \
     67     DCHECK(state_ != SPDY_ERROR);                               \
     68     DCHECK_EQ(previous_state_, state_);                         \
     69     previous_state_ = state_;                                   \
     70     state_ = newstate;                                          \
     71   } while (false)
     72 #else
     73 #define CHANGE_STATE(newstate)                                  \
     74   do {                                                          \
     75     DCHECK(state_ != SPDY_ERROR);                               \
     76     DCHECK_EQ(previous_state_, state_);                         \
     77     previous_state_ = state_;                                   \
     78     state_ = newstate;                                          \
     79   } while (false)
     80 #endif
     81 
     82 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version,
     83                                                       uint32 wire) {
     84   if (version < 3) {
     85     ConvertFlagsAndIdForSpdy2(&wire);
     86   }
     87   return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
     88 }
     89 
     90 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
     91     : flags_(flags), id_(id & 0x00ffffff) {
     92   DCHECK_GT(1u << 24, id) << "SPDY setting ID too large.";
     93 }
     94 
     95 uint32 SettingsFlagsAndId::GetWireFormat(int version) const {
     96   uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
     97   if (version < 3) {
     98     ConvertFlagsAndIdForSpdy2(&wire);
     99   }
    100   return wire;
    101 }
    102 
    103 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
    104 // This method is used to preserve buggy behavior and works on both
    105 // little-endian and big-endian hosts.
    106 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
    107 // as well as vice versa).
    108 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
    109     uint8* wire_array = reinterpret_cast<uint8*>(val);
    110     std::swap(wire_array[0], wire_array[3]);
    111     std::swap(wire_array[1], wire_array[2]);
    112 }
    113 
    114 SpdyCredential::SpdyCredential() : slot(0) {}
    115 SpdyCredential::~SpdyCredential() {}
    116 
    117 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
    118     : current_frame_buffer_(new char[kControlFrameBufferSize]),
    119       enable_compression_(true),
    120       visitor_(NULL),
    121       debug_visitor_(NULL),
    122       display_protocol_("SPDY"),
    123       spdy_version_(version),
    124       syn_frame_processed_(false),
    125       probable_http_response_(false) {
    126   DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
    127   DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
    128   Reset();
    129 }
    130 
    131 SpdyFramer::~SpdyFramer() {
    132   if (header_compressor_.get()) {
    133     deflateEnd(header_compressor_.get());
    134   }
    135   if (header_decompressor_.get()) {
    136     inflateEnd(header_decompressor_.get());
    137   }
    138 }
    139 
    140 void SpdyFramer::Reset() {
    141   state_ = SPDY_RESET;
    142   previous_state_ = SPDY_RESET;
    143   error_code_ = SPDY_NO_ERROR;
    144   remaining_data_length_ = 0;
    145   remaining_control_header_ = 0;
    146   current_frame_buffer_length_ = 0;
    147   current_frame_type_ = DATA;
    148   current_frame_flags_ = 0;
    149   current_frame_length_ = 0;
    150   current_frame_stream_id_ = kInvalidStream;
    151   settings_scratch_.Reset();
    152 }
    153 
    154 size_t SpdyFramer::GetDataFrameMinimumSize() const {
    155   // Size, in bytes, of the data frame header. Future versions of SPDY
    156   // will likely vary this, so we allow for the flexibility of a function call
    157   // for this value as opposed to a constant.
    158   return 8;
    159 }
    160 
    161 // Size, in bytes, of the control frame header.
    162 size_t SpdyFramer::GetControlFrameHeaderSize() const {
    163   switch (protocol_version()) {
    164     case SPDY2:
    165     case SPDY3:
    166     case SPDY4:
    167       return 8;
    168   }
    169   LOG(DFATAL) << "Unhandled SPDY version.";
    170   return 0;
    171 }
    172 
    173 size_t SpdyFramer::GetSynStreamMinimumSize() const {
    174   // Size, in bytes, of a SYN_STREAM frame not including the variable-length
    175   // name-value block.
    176   if (spdy_version_ < 4) {
    177     // Calculated as:
    178     // control frame header + 2 * 4 (stream IDs) + 1 (priority) + 1 (slot)
    179     return GetControlFrameHeaderSize() + 10;
    180   } else {
    181     // Calculated as:
    182     // frame prefix + 4 (associated stream ID) + 1 (priority) + 1 (slot)
    183     return GetControlFrameHeaderSize() + 6;
    184   }
    185 }
    186 
    187 size_t SpdyFramer::GetSynReplyMinimumSize() const {
    188   // Size, in bytes, of a SYN_REPLY frame not including the variable-length
    189   // name-value block.
    190   size_t size = GetControlFrameHeaderSize();
    191   if (spdy_version_ < 4) {
    192     // Calculated as:
    193     // control frame header + 4 (stream IDs)
    194     size += 4;
    195   }
    196 
    197   // In SPDY 2, there were 2 unused bytes before payload.
    198   if (protocol_version() < 3) {
    199     size += 2;
    200   }
    201 
    202   return size;
    203 }
    204 
    205 size_t SpdyFramer::GetRstStreamSize() const {
    206   // Size, in bytes, of a RST_STREAM frame.
    207   if (spdy_version_ < 4) {
    208     // Calculated as:
    209     // control frame header + 4 (stream id) + 4 (status code)
    210     return GetControlFrameHeaderSize() + 8;
    211   } else {
    212     // Calculated as:
    213     // frame prefix + 4 (status code)
    214     return GetControlFrameHeaderSize() + 4;
    215   }
    216 }
    217 
    218 size_t SpdyFramer::GetSettingsMinimumSize() const {
    219   // Size, in bytes, of a SETTINGS frame not including the IDs and values
    220   // from the variable-length value block. Calculated as:
    221   // control frame header + 4 (number of ID/value pairs)
    222   return GetControlFrameHeaderSize() + 4;
    223 }
    224 
    225 size_t SpdyFramer::GetPingSize() const {
    226   // Size, in bytes, of this PING frame. Calculated as:
    227   // control frame header + 4 (id)
    228   return GetControlFrameHeaderSize() + 4;
    229 }
    230 
    231 size_t SpdyFramer::GetGoAwaySize() const {
    232   // Size, in bytes, of this GOAWAY frame. Calculated as:
    233   // control frame header + 4 (last good stream id)
    234   size_t size = GetControlFrameHeaderSize() + 4;
    235 
    236   // SPDY 3+ GOAWAY frames also contain a status.
    237   if (protocol_version() >= 3) {
    238     size += 4;
    239   }
    240 
    241   return size;
    242 }
    243 
    244 size_t SpdyFramer::GetHeadersMinimumSize() const  {
    245   // Size, in bytes, of a HEADERS frame not including the variable-length
    246   // name-value block.
    247   size_t size = GetControlFrameHeaderSize();
    248   if (spdy_version_ < 4) {
    249     // Calculated as:
    250     // control frame header + 4 (stream IDs)
    251     size += 4;
    252   }
    253 
    254   // In SPDY 2, there were 2 unused bytes before payload.
    255   if (protocol_version() < 3) {
    256     size += 2;
    257   }
    258 
    259   return size;
    260 }
    261 
    262 size_t SpdyFramer::GetWindowUpdateSize() const {
    263   // Size, in bytes, of a WINDOW_UPDATE frame.
    264   if (spdy_version_ < 4) {
    265     // Calculated as:
    266     // control frame header + 4 (stream id) + 4 (delta)
    267     return GetControlFrameHeaderSize() + 8;
    268   } else {
    269     // Calculated as:
    270     // frame prefix + 4 (delta)
    271     return GetControlFrameHeaderSize() + 4;
    272   }
    273 }
    274 
    275 size_t SpdyFramer::GetCredentialMinimumSize() const {
    276   // Size, in bytes, of a CREDENTIAL frame sans variable-length certificate list
    277   // and proof. Calculated as:
    278   // control frame header + 2 (slot)
    279   return GetControlFrameHeaderSize() + 2;
    280 }
    281 
    282 size_t SpdyFramer::GetBlockedSize() const {
    283   DCHECK_LE(4, protocol_version());
    284   // Size, in bytes, of a BLOCKED frame.
    285   // The BLOCKED frame has no payload beyond the control frame header.
    286   return GetControlFrameHeaderSize();
    287 }
    288 
    289 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
    290   DCHECK_LE(4, protocol_version());
    291   // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
    292   // Calculated as frame prefix + 4 (promised stream id).
    293   return GetControlFrameHeaderSize() + 4;
    294 }
    295 
    296 size_t SpdyFramer::GetFrameMinimumSize() const {
    297   return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
    298 }
    299 
    300 size_t SpdyFramer::GetFrameMaximumSize() const {
    301   return (protocol_version() < 4) ? 0xffffff : 0xffff;
    302 }
    303 
    304 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
    305   return GetFrameMaximumSize() - GetDataFrameMinimumSize();
    306 }
    307 
    308 const char* SpdyFramer::StateToString(int state) {
    309   switch (state) {
    310     case SPDY_ERROR:
    311       return "ERROR";
    312     case SPDY_AUTO_RESET:
    313       return "AUTO_RESET";
    314     case SPDY_RESET:
    315       return "RESET";
    316     case SPDY_READING_COMMON_HEADER:
    317       return "READING_COMMON_HEADER";
    318     case SPDY_CONTROL_FRAME_PAYLOAD:
    319       return "CONTROL_FRAME_PAYLOAD";
    320     case SPDY_IGNORE_REMAINING_PAYLOAD:
    321       return "IGNORE_REMAINING_PAYLOAD";
    322     case SPDY_FORWARD_STREAM_FRAME:
    323       return "FORWARD_STREAM_FRAME";
    324     case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
    325       return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
    326     case SPDY_CONTROL_FRAME_HEADER_BLOCK:
    327       return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
    328     case SPDY_CREDENTIAL_FRAME_PAYLOAD:
    329       return "SPDY_CREDENTIAL_FRAME_PAYLOAD";
    330     case SPDY_SETTINGS_FRAME_PAYLOAD:
    331       return "SPDY_SETTINGS_FRAME_PAYLOAD";
    332   }
    333   return "UNKNOWN_STATE";
    334 }
    335 
    336 void SpdyFramer::set_error(SpdyError error) {
    337   DCHECK(visitor_);
    338   error_code_ = error;
    339   CHANGE_STATE(SPDY_ERROR);
    340   visitor_->OnError(this);
    341 }
    342 
    343 const char* SpdyFramer::ErrorCodeToString(int error_code) {
    344   switch (error_code) {
    345     case SPDY_NO_ERROR:
    346       return "NO_ERROR";
    347     case SPDY_INVALID_CONTROL_FRAME:
    348       return "INVALID_CONTROL_FRAME";
    349     case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
    350       return "CONTROL_PAYLOAD_TOO_LARGE";
    351     case SPDY_ZLIB_INIT_FAILURE:
    352       return "ZLIB_INIT_FAILURE";
    353     case SPDY_UNSUPPORTED_VERSION:
    354       return "UNSUPPORTED_VERSION";
    355     case SPDY_DECOMPRESS_FAILURE:
    356       return "DECOMPRESS_FAILURE";
    357     case SPDY_COMPRESS_FAILURE:
    358       return "COMPRESS_FAILURE";
    359     case SPDY_INVALID_DATA_FRAME_FLAGS:
    360       return "SPDY_INVALID_DATA_FRAME_FLAGS";
    361     case SPDY_INVALID_CONTROL_FRAME_FLAGS:
    362       return "SPDY_INVALID_CONTROL_FRAME_FLAGS";
    363   }
    364   return "UNKNOWN_ERROR";
    365 }
    366 
    367 const char* SpdyFramer::StatusCodeToString(int status_code) {
    368   switch (status_code) {
    369     case RST_STREAM_INVALID:
    370       return "INVALID";
    371     case RST_STREAM_PROTOCOL_ERROR:
    372       return "PROTOCOL_ERROR";
    373     case RST_STREAM_INVALID_STREAM:
    374       return "INVALID_STREAM";
    375     case RST_STREAM_REFUSED_STREAM:
    376       return "REFUSED_STREAM";
    377     case RST_STREAM_UNSUPPORTED_VERSION:
    378       return "UNSUPPORTED_VERSION";
    379     case RST_STREAM_CANCEL:
    380       return "CANCEL";
    381     case RST_STREAM_INTERNAL_ERROR:
    382       return "INTERNAL_ERROR";
    383     case RST_STREAM_FLOW_CONTROL_ERROR:
    384       return "FLOW_CONTROL_ERROR";
    385     case RST_STREAM_STREAM_IN_USE:
    386       return "STREAM_IN_USE";
    387     case RST_STREAM_STREAM_ALREADY_CLOSED:
    388       return "STREAM_ALREADY_CLOSED";
    389     case RST_STREAM_INVALID_CREDENTIALS:
    390       return "INVALID_CREDENTIALS";
    391     case RST_STREAM_FRAME_TOO_LARGE:
    392       return "FRAME_TOO_LARGE";
    393   }
    394   return "UNKNOWN_STATUS";
    395 }
    396 
    397 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
    398   switch (type) {
    399     case DATA:
    400       return "DATA";
    401     case SYN_STREAM:
    402       return "SYN_STREAM";
    403     case SYN_REPLY:
    404       return "SYN_REPLY";
    405     case RST_STREAM:
    406       return "RST_STREAM";
    407     case SETTINGS:
    408       return "SETTINGS";
    409     case NOOP:
    410       return "NOOP";
    411     case PING:
    412       return "PING";
    413     case GOAWAY:
    414       return "GOAWAY";
    415     case HEADERS:
    416       return "HEADERS";
    417     case WINDOW_UPDATE:
    418       return "WINDOW_UPDATE";
    419     case CREDENTIAL:
    420       return "CREDENTIAL";
    421     case BLOCKED:
    422       return "BLOCKED";
    423     case PUSH_PROMISE:
    424       return "PUSH_PROMISE";
    425   }
    426   return "UNKNOWN_CONTROL_TYPE";
    427 }
    428 
    429 size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
    430   DCHECK(visitor_);
    431   DCHECK(data);
    432 
    433   size_t original_len = len;
    434   do {
    435     previous_state_ = state_;
    436     switch (state_) {
    437       case SPDY_ERROR:
    438         goto bottom;
    439 
    440       case SPDY_AUTO_RESET:
    441       case SPDY_RESET:
    442         Reset();
    443         if (len > 0) {
    444           CHANGE_STATE(SPDY_READING_COMMON_HEADER);
    445         }
    446         break;
    447 
    448       case SPDY_READING_COMMON_HEADER: {
    449         size_t bytes_read = ProcessCommonHeader(data, len);
    450         len -= bytes_read;
    451         data += bytes_read;
    452         break;
    453       }
    454 
    455       case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
    456         // Control frames that contain header blocks
    457         // (SYN_STREAM, SYN_REPLY, HEADERS, PUSH_PROMISE)
    458         // take a different path through the state machine - they
    459         // will go:
    460         //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
    461         //   2. SPDY_CONTROL_FRAME_HEADER_BLOCK
    462         //
    463         // SETTINGS frames take a slightly modified route:
    464         //   1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
    465         //   2. SPDY_SETTINGS_FRAME_PAYLOAD
    466         //
    467         //  All other control frames will use the alternate route directly to
    468         //  SPDY_CONTROL_FRAME_PAYLOAD
    469         int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
    470         len -= bytes_read;
    471         data += bytes_read;
    472         break;
    473       }
    474 
    475       case SPDY_SETTINGS_FRAME_PAYLOAD: {
    476         int bytes_read = ProcessSettingsFramePayload(data, len);
    477         len -= bytes_read;
    478         data += bytes_read;
    479         break;
    480       }
    481 
    482       case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
    483         int bytes_read = ProcessControlFrameHeaderBlock(data, len);
    484         len -= bytes_read;
    485         data += bytes_read;
    486         break;
    487       }
    488 
    489       case SPDY_CREDENTIAL_FRAME_PAYLOAD: {
    490         size_t bytes_read = ProcessCredentialFramePayload(data, len);
    491         len -= bytes_read;
    492         data += bytes_read;
    493         break;
    494       }
    495 
    496       case SPDY_CONTROL_FRAME_PAYLOAD: {
    497         size_t bytes_read = ProcessControlFramePayload(data, len);
    498         len -= bytes_read;
    499         data += bytes_read;
    500         break;
    501       }
    502 
    503       case SPDY_IGNORE_REMAINING_PAYLOAD:
    504         // control frame has too-large payload
    505         // intentional fallthrough
    506       case SPDY_FORWARD_STREAM_FRAME: {
    507         size_t bytes_read = ProcessDataFramePayload(data, len);
    508         len -= bytes_read;
    509         data += bytes_read;
    510         break;
    511       }
    512       default:
    513         LOG(DFATAL) << "Invalid value for " << display_protocol_
    514                     << " framer state: " << state_;
    515         // This ensures that we don't infinite-loop if state_ gets an
    516         // invalid value somehow, such as due to a SpdyFramer getting deleted
    517         // from a callback it calls.
    518         goto bottom;
    519     }
    520   } while (state_ != previous_state_);
    521  bottom:
    522   DCHECK(len == 0 || state_ == SPDY_ERROR);
    523   if (current_frame_buffer_length_ == 0 &&
    524       remaining_data_length_ == 0 &&
    525       remaining_control_header_ == 0) {
    526     DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
    527         << "State: " << StateToString(state_);
    528   }
    529 
    530   return original_len - len;
    531 }
    532 
    533 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
    534   // This should only be called when we're in the SPDY_READING_COMMON_HEADER
    535   // state.
    536   DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
    537 
    538   size_t original_len = len;
    539 
    540   // Update current frame buffer as needed.
    541   if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
    542     size_t bytes_desired =
    543         GetControlFrameHeaderSize() - current_frame_buffer_length_;
    544     UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
    545   }
    546 
    547   if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
    548     // Not enough information to do anything meaningful.
    549     return original_len - len;
    550   }
    551 
    552   // Using a scoped_ptr here since we may need to create a new SpdyFrameReader
    553   // when processing DATA frames below.
    554   scoped_ptr<SpdyFrameReader> reader(
    555       new SpdyFrameReader(current_frame_buffer_.get(),
    556                           current_frame_buffer_length_));
    557 
    558   uint16 version = 0;
    559   bool is_control_frame = false;
    560 
    561   uint16 control_frame_type_field = DATA;
    562   // ProcessControlFrameHeader() will set current_frame_type_ to the
    563   // correct value if this is a valid control frame.
    564   current_frame_type_ = DATA;
    565   if (protocol_version() < 4) {
    566     bool successful_read = reader->ReadUInt16(&version);
    567     DCHECK(successful_read);
    568     is_control_frame = (version & kControlFlagMask) != 0;
    569     version &= ~kControlFlagMask;  // Only valid for control frames.
    570 
    571     if (is_control_frame) {
    572       // We check control_frame_type_field's validity in
    573       // ProcessControlFrameHeader().
    574       successful_read = reader->ReadUInt16(&control_frame_type_field);
    575     } else {
    576       reader->Rewind();
    577       successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    578     }
    579     DCHECK(successful_read);
    580 
    581     successful_read = reader->ReadUInt8(&current_frame_flags_);
    582     DCHECK(successful_read);
    583 
    584     uint32 length_field = 0;
    585     successful_read = reader->ReadUInt24(&length_field);
    586     DCHECK(successful_read);
    587     remaining_data_length_ = length_field;
    588     current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed();
    589   } else {
    590     version = protocol_version();
    591     uint16 length_field = 0;
    592     bool successful_read = reader->ReadUInt16(&length_field);
    593     DCHECK(successful_read);
    594     current_frame_length_ = length_field;
    595 
    596     uint8 control_frame_type_field_uint8 = DATA;
    597     successful_read = reader->ReadUInt8(&control_frame_type_field_uint8);
    598     DCHECK(successful_read);
    599     // We check control_frame_type_field's validity in
    600     // ProcessControlFrameHeader().
    601     control_frame_type_field = control_frame_type_field_uint8;
    602     is_control_frame = (control_frame_type_field != DATA);
    603 
    604     successful_read = reader->ReadUInt8(&current_frame_flags_);
    605     DCHECK(successful_read);
    606 
    607     successful_read = reader->ReadUInt31(&current_frame_stream_id_);
    608     DCHECK(successful_read);
    609 
    610     remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed();
    611   }
    612   DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize()
    613                              : GetDataFrameMinimumSize(),
    614             reader->GetBytesConsumed());
    615   DCHECK_EQ(current_frame_length_,
    616             remaining_data_length_ + reader->GetBytesConsumed());
    617 
    618   // This is just a sanity check for help debugging early frame errors.
    619   if (remaining_data_length_ > 1000000u) {
    620     // The strncmp for 5 is safe because we only hit this point if we
    621     // have kMinCommonHeader (8) bytes
    622     if (!syn_frame_processed_ &&
    623         strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
    624       LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_
    625                    << " request";
    626       probable_http_response_ = true;
    627     } else {
    628       LOG(WARNING) << "Unexpectedly large frame.  " << display_protocol_
    629                    << " session is likely corrupt.";
    630     }
    631   }
    632 
    633   // if we're here, then we have the common header all received.
    634   if (!is_control_frame) {
    635     if (current_frame_flags_ & ~DATA_FLAG_FIN) {
    636       set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
    637     } else {
    638       visitor_->OnDataFrameHeader(current_frame_stream_id_,
    639                                   remaining_data_length_,
    640                                   current_frame_flags_ & DATA_FLAG_FIN);
    641       if (remaining_data_length_ > 0) {
    642         CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
    643       } else {
    644         // Empty data frame.
    645         if (current_frame_flags_ & DATA_FLAG_FIN) {
    646           visitor_->OnStreamFrameData(
    647               current_frame_stream_id_, NULL, 0, true);
    648         }
    649         CHANGE_STATE(SPDY_AUTO_RESET);
    650       }
    651     }
    652   } else if (version != spdy_version_) {
    653     // We check version before we check validity: version can never be
    654     // 'invalid', it can only be unsupported.
    655     DLOG(INFO) << "Unsupported SPDY version " << version
    656                << " (expected " << spdy_version_ << ")";
    657     set_error(SPDY_UNSUPPORTED_VERSION);
    658   } else {
    659     ProcessControlFrameHeader(control_frame_type_field);
    660   }
    661 
    662   return original_len - len;
    663 }
    664 
    665 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
    666   DCHECK_EQ(SPDY_NO_ERROR, error_code_);
    667   DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);
    668 
    669   if (control_frame_type_field < FIRST_CONTROL_TYPE ||
    670       control_frame_type_field > LAST_CONTROL_TYPE) {
    671     set_error(SPDY_INVALID_CONTROL_FRAME);
    672     return;
    673   }
    674 
    675   current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field);
    676 
    677   if (current_frame_type_ == NOOP) {
    678     DLOG(INFO) << "NOOP control frame found. Ignoring.";
    679     CHANGE_STATE(SPDY_AUTO_RESET);
    680     return;
    681   }
    682 
    683   // Do some sanity checking on the control frame sizes and flags.
    684   switch (current_frame_type_) {
    685     case SYN_STREAM:
    686       if (current_frame_length_ < GetSynStreamMinimumSize()) {
    687         set_error(SPDY_INVALID_CONTROL_FRAME);
    688       } else if (current_frame_flags_ &
    689                  ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
    690         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    691       }
    692       break;
    693     case SYN_REPLY:
    694       if (current_frame_length_ < GetSynReplyMinimumSize()) {
    695         set_error(SPDY_INVALID_CONTROL_FRAME);
    696       } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
    697         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    698       }
    699       break;
    700     case RST_STREAM:
    701       if (current_frame_length_ != GetRstStreamSize()) {
    702         set_error(SPDY_INVALID_CONTROL_FRAME);
    703       } else if (current_frame_flags_ != 0) {
    704         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    705       }
    706       break;
    707     case SETTINGS:
    708       // Make sure that we have an integral number of 8-byte key/value pairs,
    709       // plus a 4-byte length field.
    710       if (current_frame_length_ < GetSettingsMinimumSize() ||
    711           (current_frame_length_ - GetControlFrameHeaderSize()) % 8 != 4) {
    712         DLOG(WARNING) << "Invalid length for SETTINGS frame: "
    713                       << current_frame_length_;
    714         set_error(SPDY_INVALID_CONTROL_FRAME);
    715       } else if (current_frame_flags_ &
    716                  ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
    717         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    718       }
    719       break;
    720     case PING:
    721       if (current_frame_length_ != GetPingSize()) {
    722         set_error(SPDY_INVALID_CONTROL_FRAME);
    723       } else if (current_frame_flags_ != 0) {
    724         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    725       }
    726       break;
    727     case GOAWAY:
    728       {
    729         if (current_frame_length_ != GetGoAwaySize()) {
    730           set_error(SPDY_INVALID_CONTROL_FRAME);
    731         } else if (current_frame_flags_ != 0) {
    732           set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    733         }
    734         break;
    735       }
    736     case HEADERS:
    737       if (current_frame_length_ < GetHeadersMinimumSize()) {
    738         set_error(SPDY_INVALID_CONTROL_FRAME);
    739       } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
    740         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    741       }
    742       break;
    743     case WINDOW_UPDATE:
    744       if (current_frame_length_ != GetWindowUpdateSize()) {
    745         set_error(SPDY_INVALID_CONTROL_FRAME);
    746       } else if (current_frame_flags_ != 0) {
    747         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    748       }
    749       break;
    750     case CREDENTIAL:
    751       if (current_frame_length_ < GetCredentialMinimumSize()) {
    752         set_error(SPDY_INVALID_CONTROL_FRAME);
    753       } else if (current_frame_flags_ != 0) {
    754         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    755       }
    756       break;
    757     case BLOCKED:
    758       if (current_frame_length_ != GetBlockedSize()) {
    759         set_error(SPDY_INVALID_CONTROL_FRAME);
    760       } else if (current_frame_flags_ != 0) {
    761         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    762       }
    763       break;
    764     case PUSH_PROMISE:
    765       if (current_frame_length_ < GetPushPromiseMinimumSize()) {
    766         set_error(SPDY_INVALID_CONTROL_FRAME);
    767       } else if (current_frame_flags_ != 0) {
    768         set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
    769       }
    770       break;
    771     default:
    772       LOG(WARNING) << "Valid " << display_protocol_
    773                    << " control frame with unhandled type: "
    774                    << current_frame_type_;
    775       // This branch should be unreachable because of the frame type bounds
    776       // check above. However, we DLOG(FATAL) here in an effort to painfully
    777       // club the head of the developer who failed to keep this file in sync
    778       // with spdy_protocol.h.
    779       DLOG(FATAL);
    780       set_error(SPDY_INVALID_CONTROL_FRAME);
    781       break;
    782   }
    783 
    784   if (state_ == SPDY_ERROR) {
    785     return;
    786   }
    787 
    788   if (current_frame_length_ > GetControlFrameBufferMaxSize()) {
    789     DLOG(WARNING) << "Received control frame with way too big of a payload: "
    790                   << current_frame_length_;
    791     set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    792     return;
    793   }
    794 
    795   if (current_frame_type_ == CREDENTIAL) {
    796     CHANGE_STATE(SPDY_CREDENTIAL_FRAME_PAYLOAD);
    797     return;
    798   }
    799 
    800   // Determine the frame size without variable-length data.
    801   int32 frame_size_without_variable_data;
    802   switch (current_frame_type_) {
    803     case SYN_STREAM:
    804       syn_frame_processed_ = true;
    805       frame_size_without_variable_data = GetSynStreamMinimumSize();
    806       break;
    807     case SYN_REPLY:
    808       syn_frame_processed_ = true;
    809       frame_size_without_variable_data = GetSynReplyMinimumSize();
    810       break;
    811     case SETTINGS:
    812       frame_size_without_variable_data = GetSettingsMinimumSize();
    813       break;
    814     case HEADERS:
    815       frame_size_without_variable_data = GetHeadersMinimumSize();
    816       break;
    817     case PUSH_PROMISE:
    818       frame_size_without_variable_data = GetPushPromiseMinimumSize();
    819       break;
    820     default:
    821       frame_size_without_variable_data = -1;
    822       break;
    823   }
    824 
    825   if ((frame_size_without_variable_data == -1) &&
    826       (current_frame_length_ > kControlFrameBufferSize)) {
    827     // We should already be in an error state. Double-check.
    828     DCHECK_EQ(SPDY_ERROR, state_);
    829     if (state_ != SPDY_ERROR) {
    830       LOG(DFATAL) << display_protocol_
    831                   << " control frame buffer too small for fixed-length frame.";
    832       set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
    833     }
    834     return;
    835   }
    836 
    837   if (frame_size_without_variable_data > 0) {
    838     // We have a control frame with a header block. We need to parse the
    839     // remainder of the control frame's header before we can parse the header
    840     // block. The start of the header block varies with the control type.
    841     DCHECK_GE(frame_size_without_variable_data,
    842               static_cast<int32>(current_frame_buffer_length_));
    843     remaining_control_header_ = frame_size_without_variable_data -
    844         current_frame_buffer_length_;
    845 
    846     CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
    847     return;
    848   }
    849 
    850   CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
    851 }
    852 
    853 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
    854                                             size_t max_bytes) {
    855   size_t bytes_to_read = std::min(*len, max_bytes);
    856   if (bytes_to_read > 0) {
    857     DCHECK_GE(kControlFrameBufferSize,
    858               current_frame_buffer_length_ + bytes_to_read);
    859     memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
    860            *data,
    861            bytes_to_read);
    862     current_frame_buffer_length_ += bytes_to_read;
    863     *data += bytes_to_read;
    864     *len -= bytes_to_read;
    865   }
    866   return bytes_to_read;
    867 }
    868 
    869 size_t SpdyFramer::GetSerializedLength(const int spdy_version,
    870                                        const SpdyHeaderBlock* headers) {
    871   const size_t num_name_value_pairs_size
    872       = (spdy_version < 3) ? sizeof(uint16) : sizeof(uint32);
    873   const size_t length_of_name_size = num_name_value_pairs_size;
    874   const size_t length_of_value_size = num_name_value_pairs_size;
    875 
    876   size_t total_length = num_name_value_pairs_size;
    877   for (SpdyHeaderBlock::const_iterator it = headers->begin();
    878        it != headers->end();
    879        ++it) {
    880     // We add space for the length of the name and the length of the value as
    881     // well as the length of the name and the length of the value.
    882     total_length += length_of_name_size + it->first.size() +
    883                     length_of_value_size + it->second.size();
    884   }
    885   return total_length;
    886 }
    887 
    888 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
    889                                   const int spdy_version,
    890                                   const SpdyHeaderBlock* headers) {
    891   if (spdy_version < 3) {
    892     frame->WriteUInt16(headers->size());  // Number of headers.
    893   } else {
    894     frame->WriteUInt32(headers->size());  // Number of headers.
    895   }
    896   SpdyHeaderBlock::const_iterator it;
    897   for (it = headers->begin(); it != headers->end(); ++it) {
    898     if (spdy_version < 3) {
    899       frame->WriteString(it->first);
    900       frame->WriteString(it->second);
    901     } else {
    902       frame->WriteStringPiece32(it->first);
    903       frame->WriteStringPiece32(it->second);
    904     }
    905   }
    906 }
    907 
    908 // TODO(phajdan.jr): Clean up after we no longer need
    909 // to workaround http://crbug.com/139744.
    910 #if !defined(USE_SYSTEM_ZLIB)
    911 
    912 // These constants are used by zlib to differentiate between normal data and
    913 // cookie data. Cookie data is handled specially by zlib when compressing.
    914 enum ZDataClass {
    915   // kZStandardData is compressed normally, save that it will never match
    916   // against any other class of data in the window.
    917   kZStandardData = Z_CLASS_STANDARD,
    918   // kZCookieData is compressed in its own Huffman blocks and only matches in
    919   // its entirety and only against other kZCookieData blocks. Any matches must
    920   // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
    921   // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
    922   // prefix matches.
    923   kZCookieData = Z_CLASS_COOKIE,
    924   // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
    925   // against the window.
    926   kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
    927 };
    928 
    929 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
    930 // needed when switching between classes of data.
    931 static void WriteZ(const base::StringPiece& data,
    932                    ZDataClass clas,
    933                    z_stream* out) {
    934   int rv;
    935 
    936   // If we are switching from standard to non-standard data then we need to end
    937   // the current Huffman context to avoid it leaking between them.
    938   if (out->clas == kZStandardData &&
    939       clas != kZStandardData) {
    940     out->avail_in = 0;
    941     rv = deflate(out, Z_PARTIAL_FLUSH);
    942     DCHECK_EQ(Z_OK, rv);
    943     DCHECK_EQ(0u, out->avail_in);
    944     DCHECK_LT(0u, out->avail_out);
    945   }
    946 
    947   out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
    948   out->avail_in = data.size();
    949   out->clas = clas;
    950   if (clas == kZStandardData) {
    951     rv = deflate(out, Z_NO_FLUSH);
    952   } else {
    953     rv = deflate(out, Z_PARTIAL_FLUSH);
    954   }
    955   if (!data.empty()) {
    956     // If we didn't provide any data then zlib will return Z_BUF_ERROR.
    957     DCHECK_EQ(Z_OK, rv);
    958   }
    959   DCHECK_EQ(0u, out->avail_in);
    960   DCHECK_LT(0u, out->avail_out);
    961 }
    962 
    963 // WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
    964 static void WriteLengthZ(size_t n,
    965                          unsigned length,
    966                          ZDataClass clas,
    967                          z_stream* out) {
    968   char buf[4];
    969   DCHECK_LE(length, sizeof(buf));
    970   for (unsigned i = 1; i <= length; i++) {
    971     buf[length - i] = n;
    972     n >>= 8;
    973   }
    974   WriteZ(base::StringPiece(buf, length), clas, out);
    975 }
    976 
    977 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
    978 // manner that resists the length of the compressed data from compromising
    979 // cookie data.
    980 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
    981                                      z_stream* z) const {
    982   unsigned length_length = 4;
    983   if (spdy_version_ < 3)
    984     length_length = 2;
    985 
    986   WriteLengthZ(headers->size(), length_length, kZStandardData, z);
    987 
    988   std::map<std::string, std::string>::const_iterator it;
    989   for (it = headers->begin(); it != headers->end(); ++it) {
    990     WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
    991     WriteZ(it->first, kZStandardData, z);
    992 
    993     if (it->first == "cookie") {
    994       // We require the cookie values (save for the last) to end with a
    995       // semicolon and (save for the first) to start with a space. This is
    996       // typically the format that we are given them in but we reserialize them
    997       // to be sure.
    998 
    999       std::vector<base::StringPiece> cookie_values;
   1000       size_t cookie_length = 0;
   1001       base::StringPiece cookie_data(it->second);
   1002 
   1003       for (;;) {
   1004         while (!cookie_data.empty() &&
   1005                (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
   1006           cookie_data.remove_prefix(1);
   1007         }
   1008         if (cookie_data.empty())
   1009           break;
   1010 
   1011         size_t i;
   1012         for (i = 0; i < cookie_data.size(); i++) {
   1013           if (cookie_data[i] == ';')
   1014             break;
   1015         }
   1016         if (i < cookie_data.size()) {
   1017           cookie_values.push_back(cookie_data.substr(0, i));
   1018           cookie_length += i + 2 /* semicolon and space */;
   1019           cookie_data.remove_prefix(i + 1);
   1020         } else {
   1021           cookie_values.push_back(cookie_data);
   1022           cookie_length += cookie_data.size();
   1023           cookie_data.remove_prefix(i);
   1024         }
   1025       }
   1026 
   1027       WriteLengthZ(cookie_length, length_length, kZStandardData, z);
   1028       for (size_t i = 0; i < cookie_values.size(); i++) {
   1029         std::string cookie;
   1030         // Since zlib will only back-reference complete cookies, a cookie that
   1031         // is currently last (and so doesn't have a trailing semicolon) won't
   1032         // match if it's later in a non-final position. The same is true of
   1033         // the first cookie.
   1034         if (i == 0 && cookie_values.size() == 1) {
   1035           cookie = cookie_values[i].as_string();
   1036         } else if (i == 0) {
   1037           cookie = cookie_values[i].as_string() + ";";
   1038         } else if (i < cookie_values.size() - 1) {
   1039           cookie = " " + cookie_values[i].as_string() + ";";
   1040         } else {
   1041           cookie = " " + cookie_values[i].as_string();
   1042         }
   1043         WriteZ(cookie, kZCookieData, z);
   1044       }
   1045     } else if (it->first == "accept" ||
   1046                it->first == "accept-charset" ||
   1047                it->first == "accept-encoding" ||
   1048                it->first == "accept-language" ||
   1049                it->first == "host" ||
   1050                it->first == "version" ||
   1051                it->first == "method" ||
   1052                it->first == "scheme" ||
   1053                it->first == ":host" ||
   1054                it->first == ":version" ||
   1055                it->first == ":method" ||
   1056                it->first == ":scheme" ||
   1057                it->first == "user-agent") {
   1058       WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
   1059       WriteZ(it->second, kZStandardData, z);
   1060     } else {
   1061       // Non-whitelisted headers are Huffman compressed in their own block, but
   1062       // don't match against the window.
   1063       WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
   1064       WriteZ(it->second, kZHuffmanOnlyData, z);
   1065     }
   1066   }
   1067 
   1068   z->avail_in = 0;
   1069   int rv = deflate(z, Z_SYNC_FLUSH);
   1070   DCHECK_EQ(Z_OK, rv);
   1071   z->clas = kZStandardData;
   1072 }
   1073 #endif  // !defined(USE_SYSTEM_ZLIB)
   1074 
   1075 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
   1076                                                         size_t len) {
   1077   DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
   1078   size_t original_len = len;
   1079 
   1080   if (remaining_control_header_ > 0) {
   1081     size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
   1082                                                  remaining_control_header_);
   1083     remaining_control_header_ -= bytes_read;
   1084     remaining_data_length_ -= bytes_read;
   1085   }
   1086 
   1087   if (remaining_control_header_ == 0) {
   1088     SpdyFrameReader reader(current_frame_buffer_.get(),
   1089                            current_frame_buffer_length_);
   1090     reader.Seek(GetControlFrameHeaderSize());  // Seek past frame header.
   1091 
   1092     switch (current_frame_type_) {
   1093       case SYN_STREAM:
   1094         {
   1095           bool successful_read = true;
   1096           if (spdy_version_ < 4) {
   1097             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1098             DCHECK(successful_read);
   1099           }
   1100           if (current_frame_stream_id_ == 0) {
   1101             set_error(SPDY_INVALID_CONTROL_FRAME);
   1102             break;
   1103           }
   1104 
   1105           SpdyStreamId associated_to_stream_id = kInvalidStream;
   1106           successful_read = reader.ReadUInt31(&associated_to_stream_id);
   1107           DCHECK(successful_read);
   1108 
   1109           SpdyPriority priority = 0;
   1110           successful_read = reader.ReadUInt8(&priority);
   1111           DCHECK(successful_read);
   1112           if (protocol_version() < 3) {
   1113             priority = priority >> 6;
   1114           } else {
   1115             priority = priority >> 5;
   1116           }
   1117 
   1118           uint8 slot = 0;
   1119           if (protocol_version() < 3) {
   1120             // SPDY 2 had an unused byte here. Seek past it.
   1121             reader.Seek(1);
   1122           } else {
   1123             successful_read = reader.ReadUInt8(&slot);
   1124             DCHECK(successful_read);
   1125           }
   1126 
   1127           DCHECK(reader.IsDoneReading());
   1128           if (debug_visitor_) {
   1129             debug_visitor_->OnReceiveCompressedFrame(
   1130                 current_frame_stream_id_,
   1131                 current_frame_type_,
   1132                 current_frame_length_);
   1133           }
   1134           visitor_->OnSynStream(
   1135               current_frame_stream_id_,
   1136               associated_to_stream_id,
   1137               priority,
   1138               slot,
   1139               (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
   1140               (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
   1141         }
   1142         CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   1143         break;
   1144       case SETTINGS:
   1145         visitor_->OnSettings(current_frame_flags_ &
   1146                              SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
   1147         CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
   1148         break;
   1149       case SYN_REPLY:
   1150       case HEADERS:
   1151         // SYN_REPLY and HEADERS are the same, save for the visitor call.
   1152         {
   1153           bool successful_read = true;
   1154           if (spdy_version_ < 4) {
   1155             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1156             DCHECK(successful_read);
   1157           }
   1158           if (current_frame_stream_id_ == 0) {
   1159             set_error(SPDY_INVALID_CONTROL_FRAME);
   1160             break;
   1161           }
   1162           if (protocol_version() < 3) {
   1163             // SPDY 2 had two unused bytes here. Seek past them.
   1164             reader.Seek(2);
   1165           }
   1166           DCHECK(reader.IsDoneReading());
   1167           if (debug_visitor_) {
   1168             debug_visitor_->OnReceiveCompressedFrame(
   1169                 current_frame_stream_id_,
   1170                 current_frame_type_,
   1171                 current_frame_length_);
   1172           }
   1173           if (current_frame_type_ == SYN_REPLY) {
   1174             visitor_->OnSynReply(
   1175                 current_frame_stream_id_,
   1176                 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
   1177           } else {
   1178             visitor_->OnHeaders(
   1179                 current_frame_stream_id_,
   1180                 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
   1181           }
   1182         }
   1183         CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   1184         break;
   1185       case PUSH_PROMISE:
   1186         {
   1187           DCHECK_LE(4, protocol_version());
   1188           if (current_frame_stream_id_ == 0) {
   1189             set_error(SPDY_INVALID_CONTROL_FRAME);
   1190             break;
   1191           }
   1192           SpdyStreamId promised_stream_id = kInvalidStream;
   1193           bool successful_read = reader.ReadUInt31(&promised_stream_id);
   1194           DCHECK(successful_read);
   1195           DCHECK(reader.IsDoneReading());
   1196           if (promised_stream_id == 0) {
   1197             set_error(SPDY_INVALID_CONTROL_FRAME);
   1198             break;
   1199           }
   1200           if (debug_visitor_) {
   1201             debug_visitor_->OnReceiveCompressedFrame(
   1202                 current_frame_stream_id_,
   1203                 current_frame_type_,
   1204                 current_frame_length_);
   1205           }
   1206           visitor_->OnPushPromise(current_frame_stream_id_, promised_stream_id);
   1207         }
   1208         CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
   1209         break;
   1210       default:
   1211         DCHECK(false);
   1212     }
   1213   }
   1214   return original_len - len;
   1215 }
   1216 
   1217 // Does not buffer the control payload. Instead, either passes directly to the
   1218 // visitor or decompresses and then passes directly to the visitor, via
   1219 // IncrementallyDeliverControlFrameHeaderData() or
   1220 // IncrementallyDecompressControlFrameHeaderData() respectively.
   1221 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
   1222                                                   size_t data_len) {
   1223   DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
   1224 
   1225   bool processed_successfully = true;
   1226   if (current_frame_type_ != SYN_STREAM &&
   1227       current_frame_type_ != SYN_REPLY &&
   1228       current_frame_type_ != HEADERS &&
   1229       current_frame_type_ != PUSH_PROMISE) {
   1230     LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
   1231   }
   1232   size_t process_bytes = std::min(data_len, remaining_data_length_);
   1233   if (process_bytes > 0) {
   1234     if (enable_compression_) {
   1235       processed_successfully = IncrementallyDecompressControlFrameHeaderData(
   1236           current_frame_stream_id_, data, process_bytes);
   1237     } else {
   1238       processed_successfully = IncrementallyDeliverControlFrameHeaderData(
   1239           current_frame_stream_id_, data, process_bytes);
   1240     }
   1241 
   1242     remaining_data_length_ -= process_bytes;
   1243   }
   1244 
   1245   // Handle the case that there is no futher data in this frame.
   1246   if (remaining_data_length_ == 0 && processed_successfully) {
   1247     // The complete header block has been delivered. We send a zero-length
   1248     // OnControlFrameHeaderData() to indicate this.
   1249     visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
   1250 
   1251     // If this is a FIN, tell the caller.
   1252     if (current_frame_flags_ & CONTROL_FLAG_FIN) {
   1253       visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
   1254     }
   1255 
   1256     CHANGE_STATE(SPDY_AUTO_RESET);
   1257   }
   1258 
   1259   // Handle error.
   1260   if (!processed_successfully) {
   1261     return data_len;
   1262   }
   1263 
   1264   // Return amount processed.
   1265   return process_bytes;
   1266 }
   1267 
   1268 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
   1269                                                size_t data_len) {
   1270   DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
   1271   DCHECK_EQ(SETTINGS, current_frame_type_);
   1272   size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
   1273   size_t processed_bytes = 0;
   1274 
   1275   // Loop over our incoming data.
   1276   while (unprocessed_bytes > 0) {
   1277     // Process up to one setting at a time.
   1278     size_t processing = std::min(
   1279         unprocessed_bytes,
   1280         static_cast<size_t>(8 - settings_scratch_.setting_buf_len));
   1281 
   1282     // Check if we have a complete setting in our input.
   1283     if (processing == 8) {
   1284       // Parse the setting directly out of the input without buffering.
   1285       if (!ProcessSetting(data + processed_bytes)) {
   1286         set_error(SPDY_INVALID_CONTROL_FRAME);
   1287         return processed_bytes;
   1288       }
   1289     } else {
   1290       // Continue updating settings_scratch_.setting_buf.
   1291       memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
   1292              data + processed_bytes,
   1293              processing);
   1294       settings_scratch_.setting_buf_len += processing;
   1295 
   1296       // Check if we have a complete setting buffered.
   1297       if (settings_scratch_.setting_buf_len == 8) {
   1298         if (!ProcessSetting(settings_scratch_.setting_buf)) {
   1299           set_error(SPDY_INVALID_CONTROL_FRAME);
   1300           return processed_bytes;
   1301         }
   1302         // Reset settings_scratch_.setting_buf for our next setting.
   1303         settings_scratch_.setting_buf_len = 0;
   1304       }
   1305     }
   1306 
   1307     // Iterate.
   1308     unprocessed_bytes -= processing;
   1309     processed_bytes += processing;
   1310   }
   1311 
   1312   // Check if we're done handling this SETTINGS frame.
   1313   remaining_data_length_ -= processed_bytes;
   1314   if (remaining_data_length_ == 0) {
   1315     CHANGE_STATE(SPDY_AUTO_RESET);
   1316   }
   1317 
   1318   return processed_bytes;
   1319 }
   1320 
   1321 bool SpdyFramer::ProcessSetting(const char* data) {
   1322   // Extract fields.
   1323   // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
   1324   const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
   1325   SettingsFlagsAndId id_and_flags =
   1326       SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire);
   1327   uint8 flags = id_and_flags.flags();
   1328   uint32 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
   1329 
   1330   // Validate id.
   1331   switch (id_and_flags.id()) {
   1332     case SETTINGS_UPLOAD_BANDWIDTH:
   1333     case SETTINGS_DOWNLOAD_BANDWIDTH:
   1334     case SETTINGS_ROUND_TRIP_TIME:
   1335     case SETTINGS_MAX_CONCURRENT_STREAMS:
   1336     case SETTINGS_CURRENT_CWND:
   1337     case SETTINGS_DOWNLOAD_RETRANS_RATE:
   1338     case SETTINGS_INITIAL_WINDOW_SIZE:
   1339       // Valid values.
   1340       break;
   1341     default:
   1342       DLOG(WARNING) << "Unknown SETTINGS ID: " << id_and_flags.id();
   1343       return false;
   1344   }
   1345   SpdySettingsIds id = static_cast<SpdySettingsIds>(id_and_flags.id());
   1346 
   1347   // Detect duplciates.
   1348   if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
   1349     DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
   1350                   << " in " << display_protocol_ << " SETTINGS frame "
   1351                   << "(last settikng id was "
   1352                   << settings_scratch_.last_setting_id << ").";
   1353     return false;
   1354   }
   1355   settings_scratch_.last_setting_id = id;
   1356 
   1357   // Validate flags.
   1358   uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
   1359   if ((flags & ~(kFlagsMask)) != 0) {
   1360     DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
   1361                   << flags;
   1362     return false;
   1363   }
   1364 
   1365   // Validation succeeded. Pass on to visitor.
   1366   visitor_->OnSetting(id, flags, value);
   1367   return true;
   1368 }
   1369 
   1370 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
   1371   size_t original_len = len;
   1372   size_t bytes_read =
   1373       UpdateCurrentFrameBuffer(&data, &len, remaining_data_length_);
   1374   remaining_data_length_ -= bytes_read;
   1375   if (remaining_data_length_ == 0) {
   1376     SpdyFrameReader reader(current_frame_buffer_.get(),
   1377                            current_frame_buffer_length_);
   1378     reader.Seek(GetControlFrameHeaderSize());  // Skip frame header.
   1379 
   1380     // Use frame-specific handlers.
   1381     switch (current_frame_type_) {
   1382       case RST_STREAM: {
   1383           bool successful_read = true;
   1384           if (spdy_version_ < 4) {
   1385             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1386             DCHECK(successful_read);
   1387           }
   1388           SpdyRstStreamStatus status = RST_STREAM_INVALID;
   1389           uint32 status_raw = status;
   1390           successful_read = reader.ReadUInt32(&status_raw);
   1391           DCHECK(successful_read);
   1392           if (status_raw > RST_STREAM_INVALID &&
   1393               status_raw < RST_STREAM_NUM_STATUS_CODES) {
   1394             status = static_cast<SpdyRstStreamStatus>(status_raw);
   1395           } else {
   1396             // TODO(hkhalil): Probably best to OnError here, depending on
   1397             // our interpretation of the spec. Keeping with existing liberal
   1398             // behavior for now.
   1399           }
   1400           DCHECK(reader.IsDoneReading());
   1401           visitor_->OnRstStream(current_frame_stream_id_, status);
   1402         }
   1403         break;
   1404       case PING: {
   1405           SpdyPingId id = 0;
   1406           bool successful_read = reader.ReadUInt32(&id);
   1407           DCHECK(successful_read);
   1408           DCHECK(reader.IsDoneReading());
   1409           visitor_->OnPing(id);
   1410         }
   1411         break;
   1412       case GOAWAY: {
   1413           bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1414           DCHECK(successful_read);
   1415           SpdyGoAwayStatus status = GOAWAY_OK;
   1416           if (spdy_version_ >= 3) {
   1417             uint32 status_raw = GOAWAY_OK;
   1418             successful_read = reader.ReadUInt32(&status_raw);
   1419             DCHECK(successful_read);
   1420             if (status_raw >= GOAWAY_OK &&
   1421                 status_raw < static_cast<uint32>(GOAWAY_NUM_STATUS_CODES)) {
   1422               status = static_cast<SpdyGoAwayStatus>(status_raw);
   1423             } else {
   1424               // TODO(hkhalil): Probably best to OnError here, depending on
   1425               // our interpretation of the spec. Keeping with existing liberal
   1426               // behavior for now.
   1427             }
   1428           }
   1429           DCHECK(reader.IsDoneReading());
   1430           visitor_->OnGoAway(current_frame_stream_id_, status);
   1431         }
   1432         break;
   1433       case WINDOW_UPDATE: {
   1434           uint32 delta_window_size = 0;
   1435           bool successful_read = true;
   1436           if (spdy_version_ < 4) {
   1437             successful_read = reader.ReadUInt31(&current_frame_stream_id_);
   1438             DCHECK(successful_read);
   1439           }
   1440           successful_read = reader.ReadUInt32(&delta_window_size);
   1441           DCHECK(successful_read);
   1442           DCHECK(reader.IsDoneReading());
   1443           visitor_->OnWindowUpdate(current_frame_stream_id_,
   1444                                    delta_window_size);
   1445         }
   1446         break;
   1447       case BLOCKED: {
   1448           DCHECK_LE(4, protocol_version());
   1449           DCHECK(reader.IsDoneReading());
   1450           visitor_->OnBlocked(current_frame_stream_id_);
   1451         }
   1452         break;
   1453       default:
   1454         // Unreachable.
   1455         LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
   1456     }
   1457 
   1458     CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
   1459   }
   1460   return original_len - len;
   1461 }
   1462 
   1463 size_t SpdyFramer::ProcessCredentialFramePayload(const char* data, size_t len) {
   1464   if (len > 0) {
   1465     // Clamp to the actual remaining payload.
   1466     if (len > remaining_data_length_) {
   1467       len = remaining_data_length_;
   1468     }
   1469     bool processed_succesfully = visitor_->OnCredentialFrameData(data, len);
   1470     remaining_data_length_ -= len;
   1471     if (!processed_succesfully) {
   1472       set_error(SPDY_CREDENTIAL_FRAME_CORRUPT);
   1473     } else if (remaining_data_length_ == 0) {
   1474       visitor_->OnCredentialFrameData(NULL, 0);
   1475       CHANGE_STATE(SPDY_AUTO_RESET);
   1476     }
   1477   }
   1478   return len;
   1479 }
   1480 
   1481 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
   1482   size_t original_len = len;
   1483 
   1484   if (remaining_data_length_ > 0) {
   1485     size_t amount_to_forward = std::min(remaining_data_length_, len);
   1486     if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
   1487       // Only inform the visitor if there is data.
   1488       if (amount_to_forward) {
   1489         visitor_->OnStreamFrameData(
   1490             current_frame_stream_id_, data, amount_to_forward, false);
   1491       }
   1492     }
   1493     data += amount_to_forward;
   1494     len -= amount_to_forward;
   1495     remaining_data_length_ -= amount_to_forward;
   1496 
   1497     // If the FIN flag is set, and there is no more data in this data
   1498     // frame, inform the visitor of EOF via a 0-length data frame.
   1499     if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) {
   1500       visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
   1501     }
   1502   }
   1503 
   1504   if (remaining_data_length_ == 0) {
   1505     CHANGE_STATE(SPDY_AUTO_RESET);
   1506   }
   1507   return original_len - len;
   1508 }
   1509 
   1510 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
   1511                                           size_t header_length,
   1512                                           SpdyHeaderBlock* block) const {
   1513   SpdyFrameReader reader(header_data, header_length);
   1514 
   1515   // Read number of headers.
   1516   uint32 num_headers;
   1517   if (spdy_version_ < 3) {
   1518     uint16 temp;
   1519     if (!reader.ReadUInt16(&temp)) {
   1520       DLOG(INFO) << "Unable to read number of headers.";
   1521       return 0;
   1522     }
   1523     num_headers = temp;
   1524   } else {
   1525     if (!reader.ReadUInt32(&num_headers)) {
   1526       DLOG(INFO) << "Unable to read number of headers.";
   1527       return 0;
   1528     }
   1529   }
   1530 
   1531   // Read each header.
   1532   for (uint32 index = 0; index < num_headers; ++index) {
   1533     base::StringPiece temp;
   1534 
   1535     // Read header name.
   1536     if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
   1537                             : !reader.ReadStringPiece32(&temp)) {
   1538       DLOG(INFO) << "Unable to read header name (" << index + 1 << " of "
   1539                  << num_headers << ").";
   1540       return 0;
   1541     }
   1542     std::string name = temp.as_string();
   1543 
   1544     // Read header value.
   1545     if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp)
   1546                             : !reader.ReadStringPiece32(&temp)) {
   1547       DLOG(INFO) << "Unable to read header value (" << index + 1 << " of "
   1548                  << num_headers << ").";
   1549       return 0;
   1550     }
   1551     std::string value = temp.as_string();
   1552 
   1553     // Ensure no duplicates.
   1554     if (block->find(name) != block->end()) {
   1555       DLOG(INFO) << "Duplicate header '" << name << "' (" << index + 1 << " of "
   1556                  << num_headers << ").";
   1557       return 0;
   1558     }
   1559 
   1560     // Store header.
   1561     (*block)[name] = value;
   1562   }
   1563   return reader.GetBytesConsumed();
   1564 }
   1565 
   1566 /* static */
   1567 bool SpdyFramer::ParseCredentialData(const char* data, size_t len,
   1568                                      SpdyCredential* credential) {
   1569   DCHECK(credential);
   1570 
   1571   SpdyFrameReader parser(data, len);
   1572   base::StringPiece temp;
   1573   if (!parser.ReadUInt16(&credential->slot)) {
   1574     return false;
   1575   }
   1576 
   1577   if (!parser.ReadStringPiece32(&temp)) {
   1578     return false;
   1579   }
   1580   credential->proof = temp.as_string();
   1581 
   1582   while (!parser.IsDoneReading()) {
   1583     if (!parser.ReadStringPiece32(&temp)) {
   1584       return false;
   1585     }
   1586     credential->certs.push_back(temp.as_string());
   1587   }
   1588   return true;
   1589 }
   1590 
   1591 SpdyFrame* SpdyFramer::CreateDataFrame(SpdyStreamId stream_id,
   1592                                        const char* data,
   1593                                        uint32 len, SpdyDataFlags flags) const {
   1594   DCHECK_EQ(0, flags & (!DATA_FLAG_FIN));
   1595 
   1596   SpdyDataIR data_ir(stream_id, base::StringPiece(data, len));
   1597   data_ir.set_fin(flags & DATA_FLAG_FIN);
   1598   return SerializeData(data_ir);
   1599 }
   1600 
   1601 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const {
   1602   const size_t kSize = GetDataFrameMinimumSize() + data.data().length();
   1603 
   1604   SpdyDataFlags flags = DATA_FLAG_NONE;
   1605   if (data.fin()) {
   1606     flags = DATA_FLAG_FIN;
   1607   }
   1608 
   1609   SpdyFrameBuilder builder(kSize);
   1610   builder.WriteDataFrameHeader(*this, data.stream_id(), flags);
   1611   builder.WriteBytes(data.data().data(), data.data().length());
   1612   DCHECK_EQ(kSize, builder.length());
   1613   return builder.take();
   1614 }
   1615 
   1616 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader(
   1617     const SpdyDataIR& data) const {
   1618   const size_t kSize = GetDataFrameMinimumSize();
   1619 
   1620   SpdyDataFlags flags = DATA_FLAG_NONE;
   1621   if (data.fin()) {
   1622     flags = DATA_FLAG_FIN;
   1623   }
   1624 
   1625   SpdyFrameBuilder builder(kSize);
   1626   builder.WriteDataFrameHeader(*this, data.stream_id(), flags);
   1627   if (protocol_version() < 4) {
   1628     builder.OverwriteLength(*this, data.data().length());
   1629   } else {
   1630     builder.OverwriteLength(*this, data.data().length() + kSize);
   1631   }
   1632   DCHECK_EQ(kSize, builder.length());
   1633   return builder.take();
   1634 }
   1635 
   1636 SpdyFrame* SpdyFramer::CreateSynStream(
   1637     SpdyStreamId stream_id,
   1638     SpdyStreamId associated_stream_id,
   1639     SpdyPriority priority,
   1640     uint8 credential_slot,
   1641     SpdyControlFlags flags,
   1642     bool compressed,
   1643     const SpdyHeaderBlock* headers) {
   1644   DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN & ~CONTROL_FLAG_UNIDIRECTIONAL);
   1645   DCHECK_EQ(enable_compression_, compressed);
   1646 
   1647   SpdySynStreamIR syn_stream(stream_id);
   1648   syn_stream.set_associated_to_stream_id(associated_stream_id);
   1649   syn_stream.set_priority(priority);
   1650   syn_stream.set_slot(credential_slot);
   1651   syn_stream.set_fin((flags & CONTROL_FLAG_FIN) != 0);
   1652   syn_stream.set_unidirectional((flags & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
   1653   // TODO(hkhalil): Avoid copy here.
   1654   *(syn_stream.GetMutableNameValueBlock()) = *headers;
   1655 
   1656   return SerializeSynStream(syn_stream);
   1657 }
   1658 
   1659 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
   1660     const SpdySynStreamIR& syn_stream) {
   1661   uint8 flags = 0;
   1662   if (syn_stream.fin()) {
   1663     flags |= CONTROL_FLAG_FIN;
   1664   }
   1665   if (syn_stream.unidirectional()) {
   1666     flags |= CONTROL_FLAG_UNIDIRECTIONAL;
   1667   }
   1668 
   1669   // The size of this frame, including variable-length name-value block.
   1670   const size_t size = GetSynStreamMinimumSize()
   1671       + GetSerializedLength(syn_stream.name_value_block());
   1672 
   1673   SpdyFrameBuilder builder(size);
   1674   if (spdy_version_ < 4) {
   1675     builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
   1676     builder.WriteUInt32(syn_stream.stream_id());
   1677   } else {
   1678     builder.WriteFramePrefix(*this,
   1679                              SYN_STREAM,
   1680                              flags,
   1681                              syn_stream.stream_id());
   1682   }
   1683   builder.WriteUInt32(syn_stream.associated_to_stream_id());
   1684   uint8 priority = syn_stream.priority();
   1685   if (priority > GetLowestPriority()) {
   1686     DLOG(DFATAL) << "Priority out-of-bounds.";
   1687     priority = GetLowestPriority();
   1688   }
   1689   builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5));
   1690   builder.WriteUInt8(syn_stream.slot());
   1691   DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
   1692   SerializeNameValueBlock(&builder, syn_stream);
   1693 
   1694   if (debug_visitor_) {
   1695     const size_t payload_len = GetSerializedLength(
   1696         protocol_version(), &(syn_stream.name_value_block()));
   1697     debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
   1698                                           SYN_STREAM,
   1699                                           payload_len,
   1700                                           builder.length());
   1701   }
   1702 
   1703   return builder.take();
   1704 }
   1705 
   1706 SpdyFrame* SpdyFramer::CreateSynReply(
   1707     SpdyStreamId stream_id,
   1708     SpdyControlFlags flags,
   1709     bool compressed,
   1710     const SpdyHeaderBlock* headers) {
   1711   DCHECK_EQ(0, flags & ~CONTROL_FLAG_FIN);
   1712   DCHECK_EQ(enable_compression_, compressed);
   1713 
   1714   SpdySynReplyIR syn_reply(stream_id);
   1715   syn_reply.set_fin(flags & CONTROL_FLAG_FIN);
   1716   // TODO(hkhalil): Avoid copy here.
   1717   *(syn_reply.GetMutableNameValueBlock()) = *headers;
   1718 
   1719   return SerializeSynReply(syn_reply);
   1720 }
   1721 
   1722 SpdySerializedFrame* SpdyFramer::SerializeSynReply(
   1723     const SpdySynReplyIR& syn_reply) {
   1724   uint8 flags = 0;
   1725   if (syn_reply.fin()) {
   1726     flags |= CONTROL_FLAG_FIN;
   1727   }
   1728 
   1729   // The size of this frame, including variable-length name-value block.
   1730   size_t size = GetSynReplyMinimumSize()
   1731       + GetSerializedLength(syn_reply.name_value_block());
   1732 
   1733   SpdyFrameBuilder builder(size);
   1734   if (spdy_version_ < 4) {
   1735     builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
   1736     builder.WriteUInt32(syn_reply.stream_id());
   1737   } else {
   1738     builder.WriteFramePrefix(*this,
   1739                              SYN_REPLY,
   1740                              flags,
   1741                              syn_reply.stream_id());
   1742   }
   1743   if (protocol_version() < 3) {
   1744     builder.WriteUInt16(0);  // Unused.
   1745   }
   1746   DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
   1747   SerializeNameValueBlock(&builder, syn_reply);
   1748 
   1749   if (debug_visitor_) {
   1750     const size_t payload_len = GetSerializedLength(
   1751         protocol_version(), &(syn_reply.name_value_block()));
   1752     debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
   1753                                           SYN_REPLY,
   1754                                           payload_len,
   1755                                           builder.length());
   1756   }
   1757 
   1758   return builder.take();
   1759 }
   1760 
   1761 SpdyFrame* SpdyFramer::CreateRstStream(
   1762     SpdyStreamId stream_id,
   1763     SpdyRstStreamStatus status) const {
   1764   SpdyRstStreamIR rst_stream(stream_id, status);
   1765   return SerializeRstStream(rst_stream);
   1766 }
   1767 
   1768 SpdySerializedFrame* SpdyFramer::SerializeRstStream(
   1769     const SpdyRstStreamIR& rst_stream) const {
   1770   SpdyFrameBuilder builder(GetRstStreamSize());
   1771   if (spdy_version_ < 4) {
   1772     builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
   1773     builder.WriteUInt32(rst_stream.stream_id());
   1774   } else {
   1775     builder.WriteFramePrefix(*this,
   1776                              RST_STREAM,
   1777                              0,
   1778                              rst_stream.stream_id());
   1779   }
   1780   builder.WriteUInt32(rst_stream.status());
   1781   DCHECK_EQ(GetRstStreamSize(), builder.length());
   1782   return builder.take();
   1783 }
   1784 
   1785 SpdyFrame* SpdyFramer::CreateSettings(
   1786     const SettingsMap& values) const {
   1787   SpdySettingsIR settings;
   1788   for (SettingsMap::const_iterator it = values.begin();
   1789        it != values.end();
   1790        ++it) {
   1791     settings.AddSetting(it->first,
   1792                         (it->second.first & SETTINGS_FLAG_PLEASE_PERSIST) != 0,
   1793                         (it->second.first & SETTINGS_FLAG_PERSISTED) != 0,
   1794                         it->second.second);
   1795   }
   1796   return SerializeSettings(settings);
   1797 }
   1798 
   1799 SpdySerializedFrame* SpdyFramer::SerializeSettings(
   1800     const SpdySettingsIR& settings) const {
   1801   uint8 flags = 0;
   1802   if (settings.clear_settings()) {
   1803     flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
   1804   }
   1805   const SpdySettingsIR::ValueMap* values = &(settings.values());
   1806 
   1807   // Size, in bytes, of this SETTINGS frame.
   1808   const size_t size = GetSettingsMinimumSize() + (values->size() * 8);
   1809 
   1810   SpdyFrameBuilder builder(size);
   1811   if (spdy_version_ < 4) {
   1812     builder.WriteControlFrameHeader(*this, SETTINGS, flags);
   1813   } else {
   1814     builder.WriteFramePrefix(*this, SETTINGS, flags, 0);
   1815   }
   1816   builder.WriteUInt32(values->size());
   1817   DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
   1818   for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
   1819        it != values->end();
   1820        ++it) {
   1821     uint8 setting_flags = 0;
   1822     if (it->second.persist_value) {
   1823       setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
   1824     }
   1825     if (it->second.persisted) {
   1826       setting_flags |= SETTINGS_FLAG_PERSISTED;
   1827     }
   1828     SettingsFlagsAndId flags_and_id(setting_flags, it->first);
   1829     uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
   1830     builder.WriteBytes(&id_and_flags_wire, 4);
   1831     builder.WriteUInt32(it->second.value);
   1832   }
   1833   DCHECK_EQ(size, builder.length());
   1834   return builder.take();
   1835 }
   1836 
   1837 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
   1838   DCHECK_LE(4, protocol_version());
   1839   SpdyFrameBuilder builder(GetBlockedSize());
   1840   builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id());
   1841   return builder.take();
   1842 }
   1843 
   1844 SpdyFrame* SpdyFramer::CreatePingFrame(uint32 unique_id) const {
   1845   SpdyPingIR ping(unique_id);
   1846   return SerializePing(ping);
   1847 }
   1848 
   1849 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
   1850   SpdyFrameBuilder builder(GetPingSize());
   1851   if (spdy_version_ < 4) {
   1852     builder.WriteControlFrameHeader(*this, PING, kNoFlags);
   1853   } else {
   1854     builder.WriteFramePrefix(*this, PING, 0, 0);
   1855   }
   1856   builder.WriteUInt32(ping.id());
   1857   DCHECK_EQ(GetPingSize(), builder.length());
   1858   return builder.take();
   1859 }
   1860 
   1861 SpdyFrame* SpdyFramer::CreateGoAway(
   1862     SpdyStreamId last_accepted_stream_id,
   1863     SpdyGoAwayStatus status) const {
   1864   SpdyGoAwayIR goaway(last_accepted_stream_id, status);
   1865   return SerializeGoAway(goaway);
   1866 }
   1867 
   1868 SpdySerializedFrame* SpdyFramer::SerializeGoAway(
   1869     const SpdyGoAwayIR& goaway) const {
   1870   SpdyFrameBuilder builder(GetGoAwaySize());
   1871   if (spdy_version_ < 4) {
   1872     builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
   1873   } else {
   1874     builder.WriteFramePrefix(*this, GOAWAY, 0, 0);
   1875   }
   1876   builder.WriteUInt32(goaway.last_good_stream_id());
   1877   if (protocol_version() >= 3) {
   1878     builder.WriteUInt32(goaway.status());
   1879   }
   1880   DCHECK_EQ(GetGoAwaySize(), builder.length());
   1881   return builder.take();
   1882 }
   1883 
   1884 SpdyFrame* SpdyFramer::CreateHeaders(
   1885     SpdyStreamId stream_id,
   1886     SpdyControlFlags flags,
   1887     bool compressed,
   1888     const SpdyHeaderBlock* header_block) {
   1889   // Basically the same as CreateSynReply().
   1890   DCHECK_EQ(0, flags & (!CONTROL_FLAG_FIN));
   1891   DCHECK_EQ(enable_compression_, compressed);
   1892 
   1893   SpdyHeadersIR headers(stream_id);
   1894   headers.set_fin(flags & CONTROL_FLAG_FIN);
   1895   // TODO(hkhalil): Avoid copy here.
   1896   *(headers.GetMutableNameValueBlock()) = *header_block;
   1897 
   1898   return SerializeHeaders(headers);
   1899 }
   1900 
   1901 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
   1902     const SpdyHeadersIR& headers) {
   1903   uint8 flags = 0;
   1904   if (headers.fin()) {
   1905     flags |= CONTROL_FLAG_FIN;
   1906   }
   1907 
   1908   // The size of this frame, including variable-length name-value block.
   1909   size_t size = GetHeadersMinimumSize()
   1910       + GetSerializedLength(headers.name_value_block());
   1911 
   1912   SpdyFrameBuilder builder(size);
   1913   if (spdy_version_ < 4) {
   1914     builder.WriteControlFrameHeader(*this, HEADERS, flags);
   1915     builder.WriteUInt32(headers.stream_id());
   1916   } else {
   1917     builder.WriteFramePrefix(*this,
   1918                              HEADERS,
   1919                              flags,
   1920                              headers.stream_id());
   1921   }
   1922   if (protocol_version() < 3) {
   1923     builder.WriteUInt16(0);  // Unused.
   1924   }
   1925   DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
   1926 
   1927   SerializeNameValueBlock(&builder, headers);
   1928 
   1929   if (debug_visitor_) {
   1930     const size_t payload_len = GetSerializedLength(
   1931         protocol_version(), &(headers.name_value_block()));
   1932     debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
   1933                                           HEADERS,
   1934                                           payload_len,
   1935                                           builder.length());
   1936   }
   1937 
   1938   return builder.take();
   1939 }
   1940 
   1941 SpdyFrame* SpdyFramer::CreateWindowUpdate(
   1942     SpdyStreamId stream_id,
   1943     uint32 delta_window_size) const {
   1944   SpdyWindowUpdateIR window_update(stream_id, delta_window_size);
   1945   return SerializeWindowUpdate(window_update);
   1946 }
   1947 
   1948 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
   1949     const SpdyWindowUpdateIR& window_update) const {
   1950   SpdyFrameBuilder builder(GetWindowUpdateSize());
   1951   if (spdy_version_ < 4) {
   1952     builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
   1953     builder.WriteUInt32(window_update.stream_id());
   1954   } else {
   1955     builder.WriteFramePrefix(*this,
   1956                              WINDOW_UPDATE,
   1957                              kNoFlags,
   1958                              window_update.stream_id());
   1959   }
   1960   builder.WriteUInt32(window_update.delta());
   1961   DCHECK_EQ(GetWindowUpdateSize(), builder.length());
   1962   return builder.take();
   1963 }
   1964 
   1965 // TODO(hkhalil): Gut with SpdyCredential removal.
   1966 SpdyFrame* SpdyFramer::CreateCredentialFrame(
   1967     const SpdyCredential& credential) const {
   1968   SpdyCredentialIR credential_ir(credential.slot);
   1969   credential_ir.set_proof(credential.proof);
   1970   for (std::vector<std::string>::const_iterator cert = credential.certs.begin();
   1971        cert != credential.certs.end();
   1972        ++cert) {
   1973     credential_ir.AddCertificate(*cert);
   1974   }
   1975   return SerializeCredential(credential_ir);
   1976 }
   1977 
   1978 SpdySerializedFrame* SpdyFramer::SerializeCredential(
   1979     const SpdyCredentialIR& credential) const {
   1980   size_t size = GetCredentialMinimumSize();
   1981   size += 4 + credential.proof().length();  // Room for proof.
   1982   for (SpdyCredentialIR::CertificateList::const_iterator it =
   1983        credential.certificates()->begin();
   1984        it != credential.certificates()->end();
   1985        ++it) {
   1986     size += 4 + it->length();  // Room for certificate.
   1987   }
   1988 
   1989   SpdyFrameBuilder builder(size);
   1990   if (spdy_version_ < 4) {
   1991     builder.WriteControlFrameHeader(*this, CREDENTIAL, kNoFlags);
   1992   } else {
   1993     builder.WriteFramePrefix(*this, CREDENTIAL, kNoFlags, 0);
   1994   }
   1995   builder.WriteUInt16(credential.slot());
   1996   DCHECK_EQ(GetCredentialMinimumSize(), builder.length());
   1997   builder.WriteStringPiece32(credential.proof());
   1998   for (SpdyCredentialIR::CertificateList::const_iterator it =
   1999        credential.certificates()->begin();
   2000        it != credential.certificates()->end();
   2001        ++it) {
   2002     builder.WriteStringPiece32(*it);
   2003   }
   2004   DCHECK_EQ(size, builder.length());
   2005   return builder.take();
   2006 }
   2007 
   2008 SpdyFrame* SpdyFramer::CreatePushPromise(
   2009     SpdyStreamId stream_id,
   2010     SpdyStreamId promised_stream_id,
   2011     const SpdyHeaderBlock* header_block) {
   2012   SpdyPushPromiseIR push_promise(stream_id, promised_stream_id);
   2013   // TODO(hkhalil): Avoid copy here.
   2014   *(push_promise.GetMutableNameValueBlock()) = *header_block;
   2015 
   2016   return SerializePushPromise(push_promise);
   2017 }
   2018 
   2019 SpdyFrame* SpdyFramer::SerializePushPromise(
   2020     const SpdyPushPromiseIR& push_promise) {
   2021   DCHECK_LE(4, protocol_version());
   2022   // The size of this frame, including variable-length name-value block.
   2023   size_t size = GetPushPromiseMinimumSize()
   2024       + GetSerializedLength(push_promise.name_value_block());
   2025 
   2026   SpdyFrameBuilder builder(size);
   2027   builder.WriteFramePrefix(*this, PUSH_PROMISE, kNoFlags,
   2028                            push_promise.stream_id());
   2029   builder.WriteUInt32(push_promise.promised_stream_id());
   2030   DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
   2031 
   2032   SerializeNameValueBlock(&builder, push_promise);
   2033 
   2034   if (debug_visitor_) {
   2035     const size_t payload_len = GetSerializedLength(
   2036         protocol_version(), &(push_promise.name_value_block()));
   2037     debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
   2038         PUSH_PROMISE, payload_len, builder.length());
   2039   }
   2040 
   2041   return builder.take();
   2042 }
   2043 
   2044 namespace {
   2045 
   2046 class FrameSerializationVisitor : public SpdyFrameVisitor {
   2047  public:
   2048   explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
   2049   virtual ~FrameSerializationVisitor() {}
   2050 
   2051   SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
   2052 
   2053   virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
   2054     frame_.reset(framer_->SerializeData(data));
   2055   }
   2056   virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE {
   2057     frame_.reset(framer_->SerializeSynStream(syn_stream));
   2058   }
   2059   virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE {
   2060     frame_.reset(framer_->SerializeSynReply(syn_reply));
   2061   }
   2062   virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE {
   2063     frame_.reset(framer_->SerializeRstStream(rst_stream));
   2064   }
   2065   virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE {
   2066     frame_.reset(framer_->SerializeSettings(settings));
   2067   }
   2068   virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE {
   2069     frame_.reset(framer_->SerializePing(ping));
   2070   }
   2071   virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE {
   2072     frame_.reset(framer_->SerializeGoAway(goaway));
   2073   }
   2074   virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE {
   2075     frame_.reset(framer_->SerializeHeaders(headers));
   2076   }
   2077   virtual void VisitWindowUpdate(
   2078       const SpdyWindowUpdateIR& window_update) OVERRIDE {
   2079     frame_.reset(framer_->SerializeWindowUpdate(window_update));
   2080   }
   2081   virtual void VisitCredential(const SpdyCredentialIR& credential) OVERRIDE {
   2082     frame_.reset(framer_->SerializeCredential(credential));
   2083   }
   2084   virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE {
   2085     frame_.reset(framer_->SerializeBlocked(blocked));
   2086   }
   2087   virtual void VisitPushPromise(
   2088       const SpdyPushPromiseIR& push_promise) OVERRIDE {
   2089     frame_.reset(framer_->SerializePushPromise(push_promise));
   2090   }
   2091 
   2092  private:
   2093   SpdyFramer* framer_;
   2094   scoped_ptr<SpdySerializedFrame> frame_;
   2095 };
   2096 
   2097 }  // namespace
   2098 
   2099 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
   2100   FrameSerializationVisitor visitor(this);
   2101   frame.Visit(&visitor);
   2102   return visitor.ReleaseSerializedFrame();
   2103 }
   2104 
   2105 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
   2106   const size_t uncompressed_length =
   2107       GetSerializedLength(protocol_version(), &headers);
   2108   if (!enable_compression_) {
   2109     return uncompressed_length;
   2110   }
   2111   z_stream* compressor = GetHeaderCompressor();
   2112   // Since we'll be performing lots of flushes when compressing the data,
   2113   // zlib's lower bounds may be insufficient.
   2114   return 2 * deflateBound(compressor, uncompressed_length);
   2115 }
   2116 
   2117 // The following compression setting are based on Brian Olson's analysis. See
   2118 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
   2119 // for more details.
   2120 #if defined(USE_SYSTEM_ZLIB)
   2121 // System zlib is not expected to have workaround for http://crbug.com/139744,
   2122 // so disable compression in that case.
   2123 // TODO(phajdan.jr): Remove the special case when it's no longer necessary.
   2124 static const int kCompressorLevel = 0;
   2125 #else  // !defined(USE_SYSTEM_ZLIB)
   2126 static const int kCompressorLevel = 9;
   2127 #endif  // !defined(USE_SYSTEM_ZLIB)
   2128 static const int kCompressorWindowSizeInBits = 11;
   2129 static const int kCompressorMemLevel = 1;
   2130 
   2131 z_stream* SpdyFramer::GetHeaderCompressor() {
   2132   if (header_compressor_.get())
   2133     return header_compressor_.get();  // Already initialized.
   2134 
   2135   header_compressor_.reset(new z_stream);
   2136   memset(header_compressor_.get(), 0, sizeof(z_stream));
   2137 
   2138   int success = deflateInit2(header_compressor_.get(),
   2139                              kCompressorLevel,
   2140                              Z_DEFLATED,
   2141                              kCompressorWindowSizeInBits,
   2142                              kCompressorMemLevel,
   2143                              Z_DEFAULT_STRATEGY);
   2144   if (success == Z_OK) {
   2145     const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
   2146                                                  : kV3Dictionary;
   2147     const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
   2148                                                     : kV3DictionarySize;
   2149     success = deflateSetDictionary(header_compressor_.get(),
   2150                                    reinterpret_cast<const Bytef*>(dictionary),
   2151                                    dictionary_size);
   2152   }
   2153   if (success != Z_OK) {
   2154     LOG(WARNING) << "deflateSetDictionary failure: " << success;
   2155     header_compressor_.reset(NULL);
   2156     return NULL;
   2157   }
   2158   return header_compressor_.get();
   2159 }
   2160 
   2161 z_stream* SpdyFramer::GetHeaderDecompressor() {
   2162   if (header_decompressor_.get())
   2163     return header_decompressor_.get();  // Already initialized.
   2164 
   2165   header_decompressor_.reset(new z_stream);
   2166   memset(header_decompressor_.get(), 0, sizeof(z_stream));
   2167 
   2168   int success = inflateInit(header_decompressor_.get());
   2169   if (success != Z_OK) {
   2170     LOG(WARNING) << "inflateInit failure: " << success;
   2171     header_decompressor_.reset(NULL);
   2172     return NULL;
   2173   }
   2174   return header_decompressor_.get();
   2175 }
   2176 
   2177 // Incrementally decompress the control frame's header block, feeding the
   2178 // result to the visitor in chunks. Continue this until the visitor
   2179 // indicates that it cannot process any more data, or (more commonly) we
   2180 // run out of data to deliver.
   2181 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
   2182     SpdyStreamId stream_id,
   2183     const char* data,
   2184     size_t len) {
   2185   // Get a decompressor or set error.
   2186   z_stream* decomp = GetHeaderDecompressor();
   2187   if (decomp == NULL) {
   2188     LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
   2189     set_error(SPDY_DECOMPRESS_FAILURE);
   2190     return false;
   2191   }
   2192 
   2193   bool processed_successfully = true;
   2194   char buffer[kHeaderDataChunkMaxSize];
   2195 
   2196   decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
   2197   decomp->avail_in = len;
   2198   // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we
   2199   // signal an error back in ProcessControlFrameBeforeHeaderBlock.  So if we've
   2200   // reached this method successfully, stream_id should be nonzero.
   2201   DCHECK_LT(0u, stream_id);
   2202   while (decomp->avail_in > 0 && processed_successfully) {
   2203     decomp->next_out = reinterpret_cast<Bytef*>(buffer);
   2204     decomp->avail_out = arraysize(buffer);
   2205 
   2206     int rv = inflate(decomp, Z_SYNC_FLUSH);
   2207     if (rv == Z_NEED_DICT) {
   2208       const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary
   2209                                                    : kV3Dictionary;
   2210       const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize
   2211                                                       : kV3DictionarySize;
   2212       const DictionaryIds& ids = g_dictionary_ids.Get();
   2213       const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id
   2214                                                       : ids.v3_dictionary_id;
   2215       // Need to try again with the right dictionary.
   2216       if (decomp->adler == dictionary_id) {
   2217         rv = inflateSetDictionary(decomp,
   2218                                   reinterpret_cast<const Bytef*>(dictionary),
   2219                                   dictionary_size);
   2220         if (rv == Z_OK)
   2221           rv = inflate(decomp, Z_SYNC_FLUSH);
   2222       }
   2223     }
   2224 
   2225     // Inflate will generate a Z_BUF_ERROR if it runs out of input
   2226     // without producing any output.  The input is consumed and
   2227     // buffered internally by zlib so we can detect this condition by
   2228     // checking if avail_in is 0 after the call to inflate.
   2229     bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
   2230     if ((rv == Z_OK) || input_exhausted) {
   2231       size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
   2232       if (decompressed_len > 0) {
   2233         processed_successfully = visitor_->OnControlFrameHeaderData(
   2234             stream_id, buffer, decompressed_len);
   2235       }
   2236       if (!processed_successfully) {
   2237         // Assume that the problem was the header block was too large for the
   2238         // visitor.
   2239         set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   2240       }
   2241     } else {
   2242       DLOG(WARNING) << "inflate failure: " << rv << " " << len;
   2243       set_error(SPDY_DECOMPRESS_FAILURE);
   2244       processed_successfully = false;
   2245     }
   2246   }
   2247   return processed_successfully;
   2248 }
   2249 
   2250 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
   2251     SpdyStreamId stream_id, const char* data, size_t len) {
   2252   bool read_successfully = true;
   2253   while (read_successfully && len > 0) {
   2254     size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
   2255     read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
   2256                                                            bytes_to_deliver);
   2257     data += bytes_to_deliver;
   2258     len -= bytes_to_deliver;
   2259     if (!read_successfully) {
   2260       // Assume that the problem was the header block was too large for the
   2261       // visitor.
   2262       set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
   2263     }
   2264   }
   2265   return read_successfully;
   2266 }
   2267 
   2268 void SpdyFramer::SerializeNameValueBlockWithoutCompression(
   2269     SpdyFrameBuilder* builder,
   2270     const SpdyNameValueBlock& name_value_block) const {
   2271   // Serialize number of headers.
   2272   if (protocol_version() < 3) {
   2273     builder->WriteUInt16(name_value_block.size());
   2274   } else {
   2275     builder->WriteUInt32(name_value_block.size());
   2276   }
   2277 
   2278   // Serialize each header.
   2279   for (SpdyHeaderBlock::const_iterator it = name_value_block.begin();
   2280        it != name_value_block.end();
   2281        ++it) {
   2282     if (protocol_version() < 3) {
   2283       builder->WriteString(it->first);
   2284       builder->WriteString(it->second);
   2285     } else {
   2286       builder->WriteStringPiece32(it->first);
   2287       builder->WriteStringPiece32(it->second);
   2288     }
   2289   }
   2290 }
   2291 
   2292 void SpdyFramer::SerializeNameValueBlock(
   2293     SpdyFrameBuilder* builder,
   2294     const SpdyFrameWithNameValueBlockIR& frame) {
   2295   if (!enable_compression_) {
   2296     return SerializeNameValueBlockWithoutCompression(builder,
   2297                                                      frame.name_value_block());
   2298   }
   2299 
   2300   // First build an uncompressed version to be fed into the compressor.
   2301   const size_t uncompressed_len = GetSerializedLength(
   2302       protocol_version(), &(frame.name_value_block()));
   2303   SpdyFrameBuilder uncompressed_builder(uncompressed_len);
   2304   SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
   2305                                             frame.name_value_block());
   2306   scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());
   2307 
   2308   z_stream* compressor = GetHeaderCompressor();
   2309   if (!compressor) {
   2310     LOG(DFATAL) << "Could not obtain compressor.";
   2311     return;
   2312   }
   2313 
   2314   base::StatsCounter compressed_frames("spdy.CompressedFrames");
   2315   base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
   2316   base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
   2317 
   2318   // Create an output frame.
   2319   // Since we'll be performing lots of flushes when compressing the data,
   2320   // zlib's lower bounds may be insufficient.
   2321   //
   2322   // TODO(akalin): Avoid the duplicate calculation with
   2323   // GetSerializedLength(const SpdyHeaderBlock&).
   2324   const int compressed_max_size =
   2325       2 * deflateBound(compressor, uncompressed_len);
   2326 
   2327   // TODO(phajdan.jr): Clean up after we no longer need
   2328   // to workaround http://crbug.com/139744.
   2329 #if defined(USE_SYSTEM_ZLIB)
   2330   compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data());
   2331   compressor->avail_in = uncompressed_len;
   2332 #endif  // defined(USE_SYSTEM_ZLIB)
   2333   compressor->next_out = reinterpret_cast<Bytef*>(
   2334       builder->GetWritableBuffer(compressed_max_size));
   2335   compressor->avail_out = compressed_max_size;
   2336 
   2337   // TODO(phajdan.jr): Clean up after we no longer need
   2338   // to workaround http://crbug.com/139744.
   2339 #if defined(USE_SYSTEM_ZLIB)
   2340   int rv = deflate(compressor, Z_SYNC_FLUSH);
   2341   if (rv != Z_OK) {  // How can we know that it compressed everything?
   2342     // This shouldn't happen, right?
   2343     LOG(WARNING) << "deflate failure: " << rv;
   2344     // TODO(akalin): Upstream this return.
   2345     return;
   2346   }
   2347 #else
   2348   WriteHeaderBlockToZ(&frame.name_value_block(), compressor);
   2349 #endif  // defined(USE_SYSTEM_ZLIB)
   2350 
   2351   int compressed_size = compressed_max_size - compressor->avail_out;
   2352   builder->Seek(compressed_size);
   2353   builder->RewriteLength(*this);
   2354 
   2355   pre_compress_bytes.Add(uncompressed_len);
   2356   post_compress_bytes.Add(compressed_size);
   2357 
   2358   compressed_frames.Increment();
   2359 }
   2360 
   2361 }  // namespace net
   2362