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