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