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