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