Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / net / spdy / spdy_framer.cc
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
20 using std::vector;
21
22 namespace net {
23
24 namespace {
25
26 // Compute the id of our dictionary so that we know we're using the
27 // right one when asked for it.
28 uLong 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
36 struct 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.
47 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
48
49 // Used to indicate no flags in a SPDY flags field.
50 const uint8 kNoFlags = 0;
51
52 }  // namespace
53
54 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
55 const 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.
59 const 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
82 SettingsFlagsAndId 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
90 SettingsFlagsAndId::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
95 uint32 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).
108 void 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
114 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
115                                                    size_t len) {
116   return true;
117 }
118
119 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
120     const char* rst_stream_data,
121     size_t len) {
122   return true;
123 }
124
125 SpdyFramer::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
139 SpdyFramer::~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
148 void 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
162 size_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.
170 size_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
181 size_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
196 size_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
214 size_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
227 size_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
234 size_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
247 size_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
263 size_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
281 size_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
294 size_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
301 size_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
308 size_t SpdyFramer::GetFrameMinimumSize() const {
309   return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
310 }
311
312 size_t SpdyFramer::GetFrameMaximumSize() const {
313   return (protocol_version() < 4) ? 0xffffff : 0xffff;
314 }
315
316 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
317   return GetFrameMaximumSize() - GetDataFrameMinimumSize();
318 }
319
320 const 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
350 void SpdyFramer::set_error(SpdyError error) {
351   DCHECK(visitor_);
352   error_code_ = error;
353   CHANGE_STATE(SPDY_ERROR);
354   visitor_->OnError(this);
355 }
356
357 const 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
381 const 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
411 const 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
443 size_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
554 size_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
686 void 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
907 size_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
923 size_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
942 void 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.
968 enum 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.
985 static 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|.
1018 static 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.
1034 void 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
1129 size_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.
1294 size_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
1341 size_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
1394 bool 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
1443 size_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
1527 size_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
1592 size_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
1657 size_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
1686 size_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
1742 SpdySerializedFrame* 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
1757 SpdySerializedFrame* 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
1777 SpdySerializedFrame* 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
1832 SpdySerializedFrame* 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
1871 SpdySerializedFrame* 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
1906 SpdySerializedFrame* 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
1944 SpdyFrame* 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
1951 SpdySerializedFrame* 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
1964 SpdySerializedFrame* 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
1999 SpdySerializedFrame* 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
2039 SpdySerializedFrame* 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
2056 SpdyFrame* 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
2081 namespace {
2082
2083 class 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
2133 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
2134   FrameSerializationVisitor visitor(this);
2135   frame.Visit(&visitor);
2136   return visitor.ReleaseSerializedFrame();
2137 }
2138
2139 size_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.
2158 static const int kCompressorLevel = 0;
2159 #else  // !defined(USE_SYSTEM_ZLIB)
2160 static const int kCompressorLevel = 9;
2161 #endif  // !defined(USE_SYSTEM_ZLIB)
2162 static const int kCompressorWindowSizeInBits = 11;
2163 static const int kCompressorMemLevel = 1;
2164
2165 z_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
2195 z_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.
2215 bool 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
2284 bool 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
2302 void 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
2326 void 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