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