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