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