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