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