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