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