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