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