Cast: Fix rtcp event dedup logic in rtcp_receiver.
[chromium-blink-merge.git] / net / spdy / spdy_framer.cc
bloba20d1ead1f83b1c433bddd0ce9ffe2b2a29db05b
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.
5 #include "net/spdy/spdy_framer.h"
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"
16 using std::string;
17 using std::vector;
19 namespace net {
21 namespace {
23 // Compute the id of our dictionary so that we know we're using the
24 // right one when asked for it.
25 uLong CalculateDictionaryId(const char* dictionary,
26 const size_t dictionary_size) {
27 uLong initial_value = adler32(0L, Z_NULL, 0);
28 return adler32(initial_value,
29 reinterpret_cast<const Bytef*>(dictionary),
30 dictionary_size);
33 struct DictionaryIds {
34 DictionaryIds()
35 : v2_dictionary_id(CalculateDictionaryId(kV2Dictionary, kV2DictionarySize)),
36 v3_dictionary_id(CalculateDictionaryId(kV3Dictionary, kV3DictionarySize))
38 const uLong v2_dictionary_id;
39 const uLong v3_dictionary_id;
42 // Adler ID for the SPDY header compressor dictionaries. Note that they are
43 // initialized lazily to avoid static initializers.
44 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
46 // Used to indicate no flags in a SPDY flags field.
47 const uint8 kNoFlags = 0;
49 } // namespace
51 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
52 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
53 // The size of the control frame buffer. Must be >= the minimum size of the
54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
55 // calculation details.
56 const size_t SpdyFramer::kControlFrameBufferSize = 18;
58 #ifdef DEBUG_SPDY_STATE_CHANGES
59 #define CHANGE_STATE(newstate) \
60 do { \
61 DVLOG(1) << "Changing state from: " \
62 << StateToString(state_) \
63 << " to " << StateToString(newstate) << "\n"; \
64 DCHECK(state_ != SPDY_ERROR); \
65 DCHECK_EQ(previous_state_, state_); \
66 previous_state_ = state_; \
67 state_ = newstate; \
68 } while (false)
69 #else
70 #define CHANGE_STATE(newstate) \
71 do { \
72 DCHECK(state_ != SPDY_ERROR); \
73 DCHECK_EQ(previous_state_, state_); \
74 previous_state_ = state_; \
75 state_ = newstate; \
76 } while (false)
77 #endif
79 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(
80 SpdyMajorVersion version, uint32 wire) {
81 if (version < SPDY3) {
82 ConvertFlagsAndIdForSpdy2(&wire);
84 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
87 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
88 : flags_(flags), id_(id & 0x00ffffff) {
89 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id;
92 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
93 const {
94 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
95 if (version < SPDY3) {
96 ConvertFlagsAndIdForSpdy2(&wire);
98 return wire;
101 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
102 // This method is used to preserve buggy behavior and works on both
103 // little-endian and big-endian hosts.
104 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
105 // as well as vice versa).
106 void SettingsFlagsAndId::ConvertFlagsAndIdForSpdy2(uint32* val) {
107 uint8* wire_array = reinterpret_cast<uint8*>(val);
108 std::swap(wire_array[0], wire_array[3]);
109 std::swap(wire_array[1], wire_array[2]);
112 bool SpdyFramerVisitorInterface::OnGoAwayFrameData(const char* goaway_data,
113 size_t len) {
114 return true;
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
118 const char* rst_stream_data,
119 size_t len) {
120 return true;
123 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
124 : current_frame_buffer_(new char[kControlFrameBufferSize]),
125 enable_compression_(true),
126 hpack_encoder_(ObtainHpackHuffmanTable()),
127 hpack_decoder_(ObtainHpackHuffmanTable()),
128 visitor_(NULL),
129 debug_visitor_(NULL),
130 display_protocol_("SPDY"),
131 spdy_version_(version),
132 syn_frame_processed_(false),
133 probable_http_response_(false),
134 expect_continuation_(0),
135 end_stream_when_done_(false) {
136 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION);
137 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION);
138 Reset();
141 SpdyFramer::~SpdyFramer() {
142 if (header_compressor_.get()) {
143 deflateEnd(header_compressor_.get());
145 if (header_decompressor_.get()) {
146 inflateEnd(header_decompressor_.get());
150 void SpdyFramer::Reset() {
151 state_ = SPDY_RESET;
152 previous_state_ = SPDY_RESET;
153 error_code_ = SPDY_NO_ERROR;
154 remaining_data_length_ = 0;
155 remaining_control_header_ = 0;
156 current_frame_buffer_length_ = 0;
157 current_frame_type_ = DATA;
158 current_frame_flags_ = 0;
159 current_frame_length_ = 0;
160 current_frame_stream_id_ = kInvalidStream;
161 settings_scratch_.Reset();
162 remaining_padding_payload_length_ = 0;
163 remaining_padding_length_fields_ = 0;
166 size_t SpdyFramer::GetDataFrameMinimumSize() const {
167 return SpdyConstants::GetDataFrameMinimumSize();
170 // Size, in bytes, of the control frame header.
171 size_t SpdyFramer::GetControlFrameHeaderSize() const {
172 return SpdyConstants::GetControlFrameHeaderSize(protocol_version());
175 size_t SpdyFramer::GetSynStreamMinimumSize() const {
176 // Size, in bytes, of a SYN_STREAM frame not including the variable-length
177 // name-value block.
178 if (protocol_version() <= SPDY3) {
179 // Calculated as:
180 // control frame header + 2 * 4 (stream IDs) + 1 (priority)
181 // + 1 (unused, was credential slot)
182 return GetControlFrameHeaderSize() + 10;
183 } else {
184 // Calculated as:
185 // frame prefix + 4 (priority)
186 return GetControlFrameHeaderSize() + 4;
190 size_t SpdyFramer::GetSynReplyMinimumSize() const {
191 // Size, in bytes, of a SYN_REPLY frame not including the variable-length
192 // name-value block.
193 size_t size = GetControlFrameHeaderSize();
194 if (protocol_version() <= SPDY3) {
195 // Calculated as:
196 // control frame header + 4 (stream IDs)
197 size += 4;
200 // In SPDY 2, there were 2 unused bytes before payload.
201 if (protocol_version() < SPDY3) {
202 size += 2;
205 return size;
208 size_t SpdyFramer::GetRstStreamMinimumSize() const {
209 // Size, in bytes, of a RST_STREAM frame.
210 if (protocol_version() <= SPDY3) {
211 // Calculated as:
212 // control frame header + 4 (stream id) + 4 (status code)
213 return GetControlFrameHeaderSize() + 8;
214 } else {
215 // Calculated as:
216 // frame prefix + 4 (status code)
217 return GetControlFrameHeaderSize() + 4;
221 size_t SpdyFramer::GetSettingsMinimumSize() const {
222 // Size, in bytes, of a SETTINGS frame not including the IDs and values
223 // from the variable-length value block. Calculated as:
224 // control frame header + 4 (number of ID/value pairs)
225 if (protocol_version() <= SPDY3) {
226 return GetControlFrameHeaderSize() + 4;
227 } else {
228 return GetControlFrameHeaderSize();
232 size_t SpdyFramer::GetPingSize() const {
233 // Size, in bytes, of this PING frame.
234 if (protocol_version() <= SPDY3) {
235 // Calculated as:
236 // control frame header + 4 (id)
237 return GetControlFrameHeaderSize() + 4;
238 } else {
239 // Calculated as:
240 // control frame header + 8 (id)
241 return GetControlFrameHeaderSize() + 8;
245 size_t SpdyFramer::GetGoAwayMinimumSize() const {
246 // Size, in bytes, of this GOAWAY frame. Calculated as:
247 // 1. Control frame header size
248 size_t size = GetControlFrameHeaderSize();
250 // 2. Last good stream id (4 bytes)
251 size += 4;
253 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
254 if (protocol_version() >= SPDY3) {
255 size += 4;
258 return size;
261 size_t SpdyFramer::GetHeadersMinimumSize() const {
262 // Size, in bytes, of a HEADERS frame not including the variable-length
263 // name-value block.
264 size_t size = GetControlFrameHeaderSize();
265 if (protocol_version() <= SPDY3) {
266 // Calculated as:
267 // control frame header + 4 (stream IDs)
268 size += 4;
271 // In SPDY 2, there were 2 unused bytes before payload.
272 if (protocol_version() <= SPDY2) {
273 size += 2;
276 return size;
279 size_t SpdyFramer::GetWindowUpdateSize() const {
280 // Size, in bytes, of a WINDOW_UPDATE frame.
281 if (protocol_version() <= SPDY3) {
282 // Calculated as:
283 // control frame header + 4 (stream id) + 4 (delta)
284 return GetControlFrameHeaderSize() + 8;
285 } else {
286 // Calculated as:
287 // frame prefix + 4 (delta)
288 return GetControlFrameHeaderSize() + 4;
292 size_t SpdyFramer::GetBlockedSize() const {
293 DCHECK_LT(SPDY3, protocol_version());
294 // Size, in bytes, of a BLOCKED frame.
295 // The BLOCKED frame has no payload beyond the control frame header.
296 return GetControlFrameHeaderSize();
299 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
300 DCHECK_LT(SPDY3, protocol_version());
301 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
302 // Calculated as frame prefix + 4 (promised stream id).
303 return GetControlFrameHeaderSize() + 4;
306 size_t SpdyFramer::GetContinuationMinimumSize() const {
307 // Size, in bytes, of a CONTINUATION frame not including the variable-length
308 // headers fragments.
309 return GetControlFrameHeaderSize();
312 size_t SpdyFramer::GetFrameMinimumSize() const {
313 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
316 size_t SpdyFramer::GetFrameMaximumSize() const {
317 return SpdyConstants::GetFrameMaximumSize(protocol_version());
320 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
321 return GetFrameMaximumSize() - GetDataFrameMinimumSize();
324 size_t SpdyFramer::GetPrefixLength(SpdyFrameType type) const {
325 return SpdyConstants::GetPrefixLength(type, protocol_version());
328 const char* SpdyFramer::StateToString(int state) {
329 switch (state) {
330 case SPDY_ERROR:
331 return "ERROR";
332 case SPDY_AUTO_RESET:
333 return "AUTO_RESET";
334 case SPDY_RESET:
335 return "RESET";
336 case SPDY_READING_COMMON_HEADER:
337 return "READING_COMMON_HEADER";
338 case SPDY_CONTROL_FRAME_PAYLOAD:
339 return "CONTROL_FRAME_PAYLOAD";
340 case SPDY_READ_PADDING_LENGTH:
341 return "SPDY_READ_PADDING_LENGTH";
342 case SPDY_CONSUME_PADDING:
343 return "SPDY_CONSUME_PADDING";
344 case SPDY_IGNORE_REMAINING_PAYLOAD:
345 return "IGNORE_REMAINING_PAYLOAD";
346 case SPDY_FORWARD_STREAM_FRAME:
347 return "FORWARD_STREAM_FRAME";
348 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
349 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
350 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
351 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
352 case SPDY_GOAWAY_FRAME_PAYLOAD:
353 return "SPDY_GOAWAY_FRAME_PAYLOAD";
354 case SPDY_RST_STREAM_FRAME_PAYLOAD:
355 return "SPDY_RST_STREAM_FRAME_PAYLOAD";
356 case SPDY_SETTINGS_FRAME_PAYLOAD:
357 return "SPDY_SETTINGS_FRAME_PAYLOAD";
359 return "UNKNOWN_STATE";
362 void SpdyFramer::set_error(SpdyError error) {
363 DCHECK(visitor_);
364 error_code_ = error;
365 // These values will usually get reset once we come to the end
366 // of a header block, but if we run into an error that
367 // might not happen, so reset them here.
368 expect_continuation_ = 0;
369 end_stream_when_done_ = false;
371 CHANGE_STATE(SPDY_ERROR);
372 visitor_->OnError(this);
375 const char* SpdyFramer::ErrorCodeToString(int error_code) {
376 switch (error_code) {
377 case SPDY_NO_ERROR:
378 return "NO_ERROR";
379 case SPDY_INVALID_CONTROL_FRAME:
380 return "INVALID_CONTROL_FRAME";
381 case SPDY_CONTROL_PAYLOAD_TOO_LARGE:
382 return "CONTROL_PAYLOAD_TOO_LARGE";
383 case SPDY_ZLIB_INIT_FAILURE:
384 return "ZLIB_INIT_FAILURE";
385 case SPDY_UNSUPPORTED_VERSION:
386 return "UNSUPPORTED_VERSION";
387 case SPDY_DECOMPRESS_FAILURE:
388 return "DECOMPRESS_FAILURE";
389 case SPDY_COMPRESS_FAILURE:
390 return "COMPRESS_FAILURE";
391 case SPDY_INVALID_DATA_FRAME_FLAGS:
392 return "SPDY_INVALID_DATA_FRAME_FLAGS";
393 case SPDY_INVALID_CONTROL_FRAME_FLAGS:
394 return "SPDY_INVALID_CONTROL_FRAME_FLAGS";
395 case SPDY_UNEXPECTED_FRAME:
396 return "UNEXPECTED_FRAME";
398 return "UNKNOWN_ERROR";
401 const char* SpdyFramer::StatusCodeToString(int status_code) {
402 switch (status_code) {
403 case RST_STREAM_INVALID:
404 return "INVALID";
405 case RST_STREAM_PROTOCOL_ERROR:
406 return "PROTOCOL_ERROR";
407 case RST_STREAM_INVALID_STREAM:
408 return "INVALID_STREAM";
409 case RST_STREAM_REFUSED_STREAM:
410 return "REFUSED_STREAM";
411 case RST_STREAM_UNSUPPORTED_VERSION:
412 return "UNSUPPORTED_VERSION";
413 case RST_STREAM_CANCEL:
414 return "CANCEL";
415 case RST_STREAM_INTERNAL_ERROR:
416 return "INTERNAL_ERROR";
417 case RST_STREAM_FLOW_CONTROL_ERROR:
418 return "FLOW_CONTROL_ERROR";
419 case RST_STREAM_STREAM_IN_USE:
420 return "STREAM_IN_USE";
421 case RST_STREAM_STREAM_ALREADY_CLOSED:
422 return "STREAM_ALREADY_CLOSED";
423 case RST_STREAM_INVALID_CREDENTIALS:
424 return "INVALID_CREDENTIALS";
425 case RST_STREAM_FRAME_TOO_LARGE:
426 return "FRAME_TOO_LARGE";
427 case RST_STREAM_CONNECT_ERROR:
428 return "CONNECT_ERROR";
429 case RST_STREAM_ENHANCE_YOUR_CALM:
430 return "ENHANCE_YOUR_CALM";
432 return "UNKNOWN_STATUS";
435 const char* SpdyFramer::FrameTypeToString(SpdyFrameType type) {
436 switch (type) {
437 case DATA:
438 return "DATA";
439 case SYN_STREAM:
440 return "SYN_STREAM";
441 case SYN_REPLY:
442 return "SYN_REPLY";
443 case RST_STREAM:
444 return "RST_STREAM";
445 case SETTINGS:
446 return "SETTINGS";
447 case NOOP:
448 return "NOOP";
449 case PING:
450 return "PING";
451 case GOAWAY:
452 return "GOAWAY";
453 case HEADERS:
454 return "HEADERS";
455 case WINDOW_UPDATE:
456 return "WINDOW_UPDATE";
457 case CREDENTIAL:
458 return "CREDENTIAL";
459 case BLOCKED:
460 return "BLOCKED";
461 case PUSH_PROMISE:
462 return "PUSH_PROMISE";
463 case CONTINUATION:
464 return "CONTINUATION";
466 return "UNKNOWN_CONTROL_TYPE";
469 size_t SpdyFramer::ProcessInput(const char* data, size_t len) {
470 DCHECK(visitor_);
471 DCHECK(data);
473 size_t original_len = len;
474 do {
475 previous_state_ = state_;
476 switch (state_) {
477 case SPDY_ERROR:
478 goto bottom;
480 case SPDY_AUTO_RESET:
481 case SPDY_RESET:
482 Reset();
483 if (len > 0) {
484 CHANGE_STATE(SPDY_READING_COMMON_HEADER);
486 break;
488 case SPDY_READING_COMMON_HEADER: {
489 size_t bytes_read = ProcessCommonHeader(data, len);
490 len -= bytes_read;
491 data += bytes_read;
492 break;
495 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: {
496 // Control frames that contain header blocks
497 // (SYN_STREAM, SYN_REPLY, HEADERS, PUSH_PROMISE, CONTINUATION)
498 // take a different path through the state machine - they
499 // will go:
500 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
501 // 2. SPDY_CONTROL_FRAME_HEADER_BLOCK
503 // SETTINGS frames take a slightly modified route:
504 // 1. SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK
505 // 2. SPDY_SETTINGS_FRAME_PAYLOAD
507 // All other control frames will use the alternate route directly to
508 // SPDY_CONTROL_FRAME_PAYLOAD
509 int bytes_read = ProcessControlFrameBeforeHeaderBlock(data, len);
510 len -= bytes_read;
511 data += bytes_read;
512 break;
515 case SPDY_SETTINGS_FRAME_PAYLOAD: {
516 int bytes_read = ProcessSettingsFramePayload(data, len);
517 len -= bytes_read;
518 data += bytes_read;
519 break;
522 case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
523 int bytes_read = ProcessControlFrameHeaderBlock(
524 data, len, protocol_version() > SPDY3);
525 len -= bytes_read;
526 data += bytes_read;
527 break;
530 case SPDY_RST_STREAM_FRAME_PAYLOAD: {
531 size_t bytes_read = ProcessRstStreamFramePayload(data, len);
532 len -= bytes_read;
533 data += bytes_read;
534 break;
537 case SPDY_GOAWAY_FRAME_PAYLOAD: {
538 size_t bytes_read = ProcessGoAwayFramePayload(data, len);
539 len -= bytes_read;
540 data += bytes_read;
541 break;
544 case SPDY_CONTROL_FRAME_PAYLOAD: {
545 size_t bytes_read = ProcessControlFramePayload(data, len);
546 len -= bytes_read;
547 data += bytes_read;
548 break;
551 case SPDY_READ_PADDING_LENGTH: {
552 size_t bytes_read = ProcessFramePaddingLength(data, len);
553 len -= bytes_read;
554 data += bytes_read;
555 break;
558 case SPDY_CONSUME_PADDING: {
559 size_t bytes_read = ProcessFramePadding(data, len);
560 len -= bytes_read;
561 data += bytes_read;
562 break;
565 case SPDY_IGNORE_REMAINING_PAYLOAD: {
566 size_t bytes_read = ProcessIgnoredControlFramePayload(/*data,*/ len);
567 len -= bytes_read;
568 data += bytes_read;
569 break;
572 case SPDY_FORWARD_STREAM_FRAME: {
573 size_t bytes_read = ProcessDataFramePayload(data, len);
574 len -= bytes_read;
575 data += bytes_read;
576 break;
579 default:
580 LOG(DFATAL) << "Invalid value for " << display_protocol_
581 << " framer state: " << state_;
582 // This ensures that we don't infinite-loop if state_ gets an
583 // invalid value somehow, such as due to a SpdyFramer getting deleted
584 // from a callback it calls.
585 goto bottom;
587 } while (state_ != previous_state_);
588 bottom:
589 DCHECK(len == 0 || state_ == SPDY_ERROR);
590 if (current_frame_buffer_length_ == 0 &&
591 remaining_data_length_ == 0 &&
592 remaining_control_header_ == 0) {
593 DCHECK(state_ == SPDY_RESET || state_ == SPDY_ERROR)
594 << "State: " << StateToString(state_);
597 return original_len - len;
600 size_t SpdyFramer::ProcessCommonHeader(const char* data, size_t len) {
601 // This should only be called when we're in the SPDY_READING_COMMON_HEADER
602 // state.
603 DCHECK_EQ(state_, SPDY_READING_COMMON_HEADER);
605 size_t original_len = len;
607 // Update current frame buffer as needed.
608 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
609 size_t bytes_desired =
610 GetControlFrameHeaderSize() - current_frame_buffer_length_;
611 UpdateCurrentFrameBuffer(&data, &len, bytes_desired);
614 if (current_frame_buffer_length_ < GetControlFrameHeaderSize()) {
615 // Not enough information to do anything meaningful.
616 return original_len - len;
619 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader
620 // when processing DATA frames below.
621 scoped_ptr<SpdyFrameReader> reader(
622 new SpdyFrameReader(current_frame_buffer_.get(),
623 current_frame_buffer_length_));
625 uint16 version = 0;
626 bool is_control_frame = false;
628 uint16 control_frame_type_field = DATA;
629 // ProcessControlFrameHeader() will set current_frame_type_ to the
630 // correct value if this is a valid control frame.
631 current_frame_type_ = DATA;
632 if (protocol_version() <= SPDY3) {
633 bool successful_read = reader->ReadUInt16(&version);
634 DCHECK(successful_read);
635 is_control_frame = (version & kControlFlagMask) != 0;
636 version &= ~kControlFlagMask; // Only valid for control frames.
637 if (is_control_frame) {
638 // We check version before we check validity: version can never be
639 // 'invalid', it can only be unsupported.
640 if (version < SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) ||
641 version > SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION) ||
642 SpdyConstants::ParseMajorVersion(version) != protocol_version()) {
643 // Version does not match the version the framer was initialized with.
644 DVLOG(1) << "Unsupported SPDY version "
645 << version
646 << " (expected " << protocol_version() << ")";
647 set_error(SPDY_UNSUPPORTED_VERSION);
648 return 0;
649 } else {
650 // Convert version from wire format to SpdyMajorVersion.
651 version = SpdyConstants::ParseMajorVersion(version);
653 // We check control_frame_type_field's validity in
654 // ProcessControlFrameHeader().
655 successful_read = reader->ReadUInt16(&control_frame_type_field);
656 } else {
657 reader->Rewind();
658 successful_read = reader->ReadUInt31(&current_frame_stream_id_);
660 DCHECK(successful_read);
662 successful_read = reader->ReadUInt8(&current_frame_flags_);
663 DCHECK(successful_read);
665 uint32 length_field = 0;
666 successful_read = reader->ReadUInt24(&length_field);
667 DCHECK(successful_read);
668 remaining_data_length_ = length_field;
669 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed();
670 } else {
671 version = protocol_version();
672 uint16 length_field = 0;
673 bool successful_read = reader->ReadUInt16(&length_field);
674 DCHECK(successful_read);
676 uint8 control_frame_type_field_uint8 = DATA;
677 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8);
678 DCHECK(successful_read);
679 // We check control_frame_type_field's validity in
680 // ProcessControlFrameHeader().
681 control_frame_type_field = control_frame_type_field_uint8;
682 is_control_frame = (control_frame_type_field != DATA);
684 if (is_control_frame) {
685 current_frame_length_ = length_field + GetControlFrameHeaderSize();
686 } else {
687 current_frame_length_ = length_field + GetDataFrameMinimumSize();
690 successful_read = reader->ReadUInt8(&current_frame_flags_);
691 DCHECK(successful_read);
693 successful_read = reader->ReadUInt31(&current_frame_stream_id_);
694 DCHECK(successful_read);
696 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed();
698 // Before we accept a DATA frame, we need to make sure we're not in the
699 // middle of processing a header block.
700 const bool is_continuation_frame = (control_frame_type_field ==
701 SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION));
702 if ((expect_continuation_ != 0) != is_continuation_frame) {
703 if (expect_continuation_ != 0) {
704 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION "
705 << "frame, but instead received frame type "
706 << control_frame_type_field;
707 } else {
708 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame.";
710 set_error(SPDY_UNEXPECTED_FRAME);
711 return original_len - len;
714 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize()
715 : GetDataFrameMinimumSize(),
716 reader->GetBytesConsumed());
717 DCHECK_EQ(current_frame_length_,
718 remaining_data_length_ + reader->GetBytesConsumed());
720 // This is just a sanity check for help debugging early frame errors.
721 if (remaining_data_length_ > 1000000u) {
722 // The strncmp for 5 is safe because we only hit this point if we
723 // have kMinCommonHeader (8) bytes
724 if (!syn_frame_processed_ &&
725 strncmp(current_frame_buffer_.get(), "HTTP/", 5) == 0) {
726 LOG(WARNING) << "Unexpected HTTP response to " << display_protocol_
727 << " request";
728 probable_http_response_ = true;
729 } else {
730 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_
731 << " session is likely corrupt.";
735 // if we're here, then we have the common header all received.
736 if (!is_control_frame) {
737 if (protocol_version() > SPDY3) {
738 // Catch bogus tests sending oversized DATA frames.
739 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_)
740 << "DATA frame too large for SPDY >= 4.";
743 uint8 valid_data_flags = 0;
744 if (protocol_version() > SPDY3) {
745 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
746 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH;
747 } else {
748 valid_data_flags = DATA_FLAG_FIN;
751 if (current_frame_flags_ & ~valid_data_flags) {
752 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
753 } else {
754 visitor_->OnDataFrameHeader(current_frame_stream_id_,
755 remaining_data_length_,
756 current_frame_flags_ & DATA_FLAG_FIN);
757 if (remaining_data_length_ > 0) {
758 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
759 } else {
760 // Empty data frame.
761 if (current_frame_flags_ & DATA_FLAG_FIN) {
762 visitor_->OnStreamFrameData(
763 current_frame_stream_id_, NULL, 0, true);
765 CHANGE_STATE(SPDY_AUTO_RESET);
768 } else {
769 ProcessControlFrameHeader(control_frame_type_field);
772 return original_len - len;
775 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
776 DCHECK_EQ(SPDY_NO_ERROR, error_code_);
777 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);
779 // Early detection of deprecated frames that we ignore.
780 if (protocol_version() <= SPDY3) {
781 if (control_frame_type_field == NOOP) {
782 current_frame_type_ = NOOP;
783 DVLOG(1) << "NOOP control frame found. Ignoring.";
784 CHANGE_STATE(SPDY_AUTO_RESET);
785 return;
788 if (control_frame_type_field == CREDENTIAL) {
789 current_frame_type_ = CREDENTIAL;
790 DCHECK_EQ(SPDY3, protocol_version());
791 DVLOG(1) << "CREDENTIAL control frame found. Ignoring.";
792 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
793 return;
797 if (!SpdyConstants::IsValidFrameType(protocol_version(),
798 control_frame_type_field)) {
799 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field
800 << " (protocol version: " << protocol_version() << ")";
801 set_error(SPDY_INVALID_CONTROL_FRAME);
802 return;
805 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(),
806 control_frame_type_field);
808 // Do some sanity checking on the control frame sizes and flags.
809 switch (current_frame_type_) {
810 case SYN_STREAM:
811 if (current_frame_length_ < GetSynStreamMinimumSize()) {
812 set_error(SPDY_INVALID_CONTROL_FRAME);
813 } else if (current_frame_flags_ &
814 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) {
815 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
817 break;
818 case SYN_REPLY:
819 if (current_frame_length_ < GetSynReplyMinimumSize()) {
820 set_error(SPDY_INVALID_CONTROL_FRAME);
821 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
822 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
824 break;
825 case RST_STREAM:
826 // For SPDY versions < 4, the header has a fixed length.
827 // For SPDY version 4 and up, the RST_STREAM frame may include optional
828 // opaque data, so we only have a lower limit on the frame size.
829 if ((current_frame_length_ != GetRstStreamMinimumSize() &&
830 protocol_version() <= SPDY3) ||
831 (current_frame_length_ < GetRstStreamMinimumSize() &&
832 protocol_version() > SPDY3)) {
833 set_error(SPDY_INVALID_CONTROL_FRAME);
834 } else if (current_frame_flags_ != 0) {
835 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
837 break;
838 case SETTINGS:
840 // Make sure that we have an integral number of 8-byte key/value pairs,
841 // plus a 4-byte length field in SPDY3 and below.
842 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0);
843 // Size of each key/value pair in bytes.
844 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
845 if (current_frame_length_ < GetSettingsMinimumSize() ||
846 (current_frame_length_ - GetControlFrameHeaderSize())
847 % setting_size != values_prefix_size) {
848 DLOG(WARNING) << "Invalid length for SETTINGS frame: "
849 << current_frame_length_;
850 set_error(SPDY_INVALID_CONTROL_FRAME);
851 } else if (protocol_version() <= SPDY3 &&
852 current_frame_flags_ &
853 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
854 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
855 } else if (protocol_version() > SPDY3 &&
856 current_frame_flags_ & ~SETTINGS_FLAG_ACK) {
857 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
858 } else if (protocol_version() > SPDY3 &&
859 current_frame_flags_ & SETTINGS_FLAG_ACK &&
860 current_frame_length_ > GetSettingsMinimumSize()) {
861 set_error(SPDY_INVALID_CONTROL_FRAME);
863 break;
865 case PING:
866 if (current_frame_length_ != GetPingSize()) {
867 set_error(SPDY_INVALID_CONTROL_FRAME);
868 } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) ||
869 (current_frame_flags_ & ~PING_FLAG_ACK)) {
870 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
872 break;
873 case GOAWAY:
875 // For SPDY version < 4, there are only mandatory fields and the header
876 // has a fixed length. For SPDY version >= 4, optional opaque data may
877 // be appended to the GOAWAY frame, thus there is only a minimal length
878 // restriction.
879 if ((current_frame_length_ != GetGoAwayMinimumSize() &&
880 protocol_version() <= SPDY3) ||
881 (current_frame_length_ < GetGoAwayMinimumSize() &&
882 protocol_version() > SPDY3)) {
883 set_error(SPDY_INVALID_CONTROL_FRAME);
884 } else if (current_frame_flags_ != 0) {
885 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
887 break;
889 case HEADERS:
891 size_t min_size = GetHeadersMinimumSize();
892 if (protocol_version() > SPDY3 &&
893 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
894 min_size += 4;
896 if (current_frame_length_ < min_size) {
897 set_error(SPDY_INVALID_CONTROL_FRAME);
898 } else if (protocol_version() <= SPDY3 &&
899 current_frame_flags_ & ~CONTROL_FLAG_FIN) {
900 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
901 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
902 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
903 HEADERS_FLAG_END_HEADERS)) {
904 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
907 break;
908 case WINDOW_UPDATE:
909 if (current_frame_length_ != GetWindowUpdateSize()) {
910 set_error(SPDY_INVALID_CONTROL_FRAME);
911 } else if (current_frame_flags_ != 0) {
912 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
914 break;
915 case BLOCKED:
916 if (current_frame_length_ != GetBlockedSize()) {
917 set_error(SPDY_INVALID_CONTROL_FRAME);
918 } else if (current_frame_flags_ != 0) {
919 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
921 break;
922 case PUSH_PROMISE:
923 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
924 set_error(SPDY_INVALID_CONTROL_FRAME);
925 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
927 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
928 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) {
929 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
931 break;
932 case CONTINUATION:
933 if (current_frame_length_ < GetContinuationMinimumSize() ||
934 protocol_version() <= SPDY3) {
935 set_error(SPDY_INVALID_CONTROL_FRAME);
936 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) {
937 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
939 break;
940 default:
941 LOG(WARNING) << "Valid " << display_protocol_
942 << " control frame with unhandled type: "
943 << current_frame_type_;
944 // This branch should be unreachable because of the frame type bounds
945 // check above. However, we DLOG(FATAL) here in an effort to painfully
946 // club the head of the developer who failed to keep this file in sync
947 // with spdy_protocol.h.
948 DLOG(FATAL);
949 set_error(SPDY_INVALID_CONTROL_FRAME);
950 break;
953 if (state_ == SPDY_ERROR) {
954 return;
957 if (current_frame_length_ > GetControlFrameBufferMaxSize()) {
958 DLOG(WARNING) << "Received control frame with way too big of a payload: "
959 << current_frame_length_;
960 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
961 return;
964 if (current_frame_type_ == GOAWAY) {
965 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD);
966 return;
969 if (current_frame_type_ == RST_STREAM) {
970 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD);
971 return;
974 // Determine the frame size without variable-length data.
975 int32 frame_size_without_variable_data;
976 switch (current_frame_type_) {
977 case SYN_STREAM:
978 syn_frame_processed_ = true;
979 frame_size_without_variable_data = GetSynStreamMinimumSize();
980 break;
981 case SYN_REPLY:
982 syn_frame_processed_ = true;
983 frame_size_without_variable_data = GetSynReplyMinimumSize();
984 break;
985 case SETTINGS:
986 frame_size_without_variable_data = GetSettingsMinimumSize();
987 break;
988 case HEADERS:
989 frame_size_without_variable_data = GetHeadersMinimumSize();
990 if (protocol_version() > SPDY3 &&
991 current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
992 frame_size_without_variable_data += 4; // priority
994 break;
995 case PUSH_PROMISE:
996 frame_size_without_variable_data = GetPushPromiseMinimumSize();
997 break;
998 case CONTINUATION:
999 frame_size_without_variable_data = GetContinuationMinimumSize();
1000 break;
1001 default:
1002 frame_size_without_variable_data = -1;
1003 break;
1006 if ((frame_size_without_variable_data == -1) &&
1007 (current_frame_length_ > kControlFrameBufferSize)) {
1008 // We should already be in an error state. Double-check.
1009 DCHECK_EQ(SPDY_ERROR, state_);
1010 if (state_ != SPDY_ERROR) {
1011 LOG(DFATAL) << display_protocol_
1012 << " control frame buffer too small for fixed-length frame.";
1013 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1015 return;
1018 if (frame_size_without_variable_data > 0) {
1019 // We have a control frame with a header block. We need to parse the
1020 // remainder of the control frame's header before we can parse the header
1021 // block. The start of the header block varies with the control type.
1022 DCHECK_GE(frame_size_without_variable_data,
1023 static_cast<int32>(current_frame_buffer_length_));
1024 remaining_control_header_ = frame_size_without_variable_data -
1025 current_frame_buffer_length_;
1027 CHANGE_STATE(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK);
1028 return;
1031 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD);
1034 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data, size_t* len,
1035 size_t max_bytes) {
1036 size_t bytes_to_read = std::min(*len, max_bytes);
1037 if (bytes_to_read > 0) {
1038 DCHECK_GE(kControlFrameBufferSize,
1039 current_frame_buffer_length_ + bytes_to_read);
1040 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
1041 *data,
1042 bytes_to_read);
1043 current_frame_buffer_length_ += bytes_to_read;
1044 *data += bytes_to_read;
1045 *len -= bytes_to_read;
1047 return bytes_to_read;
1050 size_t SpdyFramer::GetSerializedLength(
1051 const SpdyMajorVersion spdy_version,
1052 const SpdyHeaderBlock* headers) {
1053 const size_t num_name_value_pairs_size
1054 = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
1055 const size_t length_of_name_size = num_name_value_pairs_size;
1056 const size_t length_of_value_size = num_name_value_pairs_size;
1058 size_t total_length = num_name_value_pairs_size;
1059 for (SpdyHeaderBlock::const_iterator it = headers->begin();
1060 it != headers->end();
1061 ++it) {
1062 // We add space for the length of the name and the length of the value as
1063 // well as the length of the name and the length of the value.
1064 total_length += length_of_name_size + it->first.size() +
1065 length_of_value_size + it->second.size();
1067 return total_length;
1070 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
1071 const SpdyMajorVersion spdy_version,
1072 const SpdyHeaderBlock* headers) {
1073 if (spdy_version < SPDY3) {
1074 frame->WriteUInt16(headers->size()); // Number of headers.
1075 } else {
1076 frame->WriteUInt32(headers->size()); // Number of headers.
1078 SpdyHeaderBlock::const_iterator it;
1079 for (it = headers->begin(); it != headers->end(); ++it) {
1080 if (spdy_version < SPDY3) {
1081 frame->WriteString(it->first);
1082 frame->WriteString(it->second);
1083 } else {
1084 frame->WriteStringPiece32(it->first);
1085 frame->WriteStringPiece32(it->second);
1090 // TODO(phajdan.jr): Clean up after we no longer need
1091 // to workaround http://crbug.com/139744.
1092 #if !defined(USE_SYSTEM_ZLIB)
1094 // These constants are used by zlib to differentiate between normal data and
1095 // cookie data. Cookie data is handled specially by zlib when compressing.
1096 enum ZDataClass {
1097 // kZStandardData is compressed normally, save that it will never match
1098 // against any other class of data in the window.
1099 kZStandardData = Z_CLASS_STANDARD,
1100 // kZCookieData is compressed in its own Huffman blocks and only matches in
1101 // its entirety and only against other kZCookieData blocks. Any matches must
1102 // be preceeded by a kZStandardData byte, or a semicolon to prevent matching
1103 // a suffix. It's assumed that kZCookieData ends in a semicolon to prevent
1104 // prefix matches.
1105 kZCookieData = Z_CLASS_COOKIE,
1106 // kZHuffmanOnlyData is only Huffman compressed - no matches are performed
1107 // against the window.
1108 kZHuffmanOnlyData = Z_CLASS_HUFFMAN_ONLY,
1111 // WriteZ writes |data| to the deflate context |out|. WriteZ will flush as
1112 // needed when switching between classes of data.
1113 static void WriteZ(const base::StringPiece& data,
1114 ZDataClass clas,
1115 z_stream* out) {
1116 int rv;
1118 // If we are switching from standard to non-standard data then we need to end
1119 // the current Huffman context to avoid it leaking between them.
1120 if (out->clas == kZStandardData &&
1121 clas != kZStandardData) {
1122 out->avail_in = 0;
1123 rv = deflate(out, Z_PARTIAL_FLUSH);
1124 DCHECK_EQ(Z_OK, rv);
1125 DCHECK_EQ(0u, out->avail_in);
1126 DCHECK_LT(0u, out->avail_out);
1129 out->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data.data()));
1130 out->avail_in = data.size();
1131 out->clas = clas;
1132 if (clas == kZStandardData) {
1133 rv = deflate(out, Z_NO_FLUSH);
1134 } else {
1135 rv = deflate(out, Z_PARTIAL_FLUSH);
1137 if (!data.empty()) {
1138 // If we didn't provide any data then zlib will return Z_BUF_ERROR.
1139 DCHECK_EQ(Z_OK, rv);
1141 DCHECK_EQ(0u, out->avail_in);
1142 DCHECK_LT(0u, out->avail_out);
1145 // WriteLengthZ writes |n| as a |length|-byte, big-endian number to |out|.
1146 static void WriteLengthZ(size_t n,
1147 unsigned length,
1148 ZDataClass clas,
1149 z_stream* out) {
1150 char buf[4];
1151 DCHECK_LE(length, sizeof(buf));
1152 for (unsigned i = 1; i <= length; i++) {
1153 buf[length - i] = n;
1154 n >>= 8;
1156 WriteZ(base::StringPiece(buf, length), clas, out);
1159 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
1160 // manner that resists the length of the compressed data from compromising
1161 // cookie data.
1162 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
1163 z_stream* z) const {
1164 unsigned length_length = 4;
1165 if (spdy_version_ < 3)
1166 length_length = 2;
1168 WriteLengthZ(headers->size(), length_length, kZStandardData, z);
1170 std::map<std::string, std::string>::const_iterator it;
1171 for (it = headers->begin(); it != headers->end(); ++it) {
1172 WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
1173 WriteZ(it->first, kZStandardData, z);
1175 if (it->first == "cookie") {
1176 // We require the cookie values (save for the last) to end with a
1177 // semicolon and (save for the first) to start with a space. This is
1178 // typically the format that we are given them in but we reserialize them
1179 // to be sure.
1181 std::vector<base::StringPiece> cookie_values;
1182 size_t cookie_length = 0;
1183 base::StringPiece cookie_data(it->second);
1185 for (;;) {
1186 while (!cookie_data.empty() &&
1187 (cookie_data[0] == ' ' || cookie_data[0] == '\t')) {
1188 cookie_data.remove_prefix(1);
1190 if (cookie_data.empty())
1191 break;
1193 size_t i;
1194 for (i = 0; i < cookie_data.size(); i++) {
1195 if (cookie_data[i] == ';')
1196 break;
1198 if (i < cookie_data.size()) {
1199 cookie_values.push_back(cookie_data.substr(0, i));
1200 cookie_length += i + 2 /* semicolon and space */;
1201 cookie_data.remove_prefix(i + 1);
1202 } else {
1203 cookie_values.push_back(cookie_data);
1204 cookie_length += cookie_data.size();
1205 cookie_data.remove_prefix(i);
1209 WriteLengthZ(cookie_length, length_length, kZStandardData, z);
1210 for (size_t i = 0; i < cookie_values.size(); i++) {
1211 std::string cookie;
1212 // Since zlib will only back-reference complete cookies, a cookie that
1213 // is currently last (and so doesn't have a trailing semicolon) won't
1214 // match if it's later in a non-final position. The same is true of
1215 // the first cookie.
1216 if (i == 0 && cookie_values.size() == 1) {
1217 cookie = cookie_values[i].as_string();
1218 } else if (i == 0) {
1219 cookie = cookie_values[i].as_string() + ";";
1220 } else if (i < cookie_values.size() - 1) {
1221 cookie = " " + cookie_values[i].as_string() + ";";
1222 } else {
1223 cookie = " " + cookie_values[i].as_string();
1225 WriteZ(cookie, kZCookieData, z);
1227 } else if (it->first == "accept" ||
1228 it->first == "accept-charset" ||
1229 it->first == "accept-encoding" ||
1230 it->first == "accept-language" ||
1231 it->first == "host" ||
1232 it->first == "version" ||
1233 it->first == "method" ||
1234 it->first == "scheme" ||
1235 it->first == ":host" ||
1236 it->first == ":version" ||
1237 it->first == ":method" ||
1238 it->first == ":scheme" ||
1239 it->first == "user-agent") {
1240 WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
1241 WriteZ(it->second, kZStandardData, z);
1242 } else {
1243 // Non-whitelisted headers are Huffman compressed in their own block, but
1244 // don't match against the window.
1245 WriteLengthZ(it->second.size(), length_length, kZStandardData, z);
1246 WriteZ(it->second, kZHuffmanOnlyData, z);
1250 z->avail_in = 0;
1251 int rv = deflate(z, Z_SYNC_FLUSH);
1252 DCHECK_EQ(Z_OK, rv);
1253 z->clas = kZStandardData;
1255 #endif // !defined(USE_SYSTEM_ZLIB)
1257 size_t SpdyFramer::ProcessControlFrameBeforeHeaderBlock(const char* data,
1258 size_t len) {
1259 DCHECK_EQ(SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK, state_);
1260 const size_t original_len = len;
1262 if (remaining_control_header_ > 0) {
1263 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
1264 remaining_control_header_);
1265 remaining_control_header_ -= bytes_read;
1266 remaining_data_length_ -= bytes_read;
1269 if (remaining_control_header_ == 0) {
1270 SpdyFrameReader reader(current_frame_buffer_.get(),
1271 current_frame_buffer_length_);
1272 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1274 switch (current_frame_type_) {
1275 case SYN_STREAM:
1277 DCHECK_GE(SPDY3, protocol_version());
1278 bool successful_read = true;
1279 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1280 DCHECK(successful_read);
1281 if (current_frame_stream_id_ == 0) {
1282 set_error(SPDY_INVALID_CONTROL_FRAME);
1283 break;
1286 SpdyStreamId associated_to_stream_id = kInvalidStream;
1287 successful_read = reader.ReadUInt31(&associated_to_stream_id);
1288 DCHECK(successful_read);
1290 SpdyPriority priority = 0;
1291 successful_read = reader.ReadUInt8(&priority);
1292 DCHECK(successful_read);
1293 if (protocol_version() <= SPDY2) {
1294 priority = priority >> 6;
1295 } else {
1296 priority = priority >> 5;
1299 // Seek past unused byte; used to be credential slot in SPDY 3.
1300 reader.Seek(1);
1302 DCHECK(reader.IsDoneReading());
1303 if (debug_visitor_) {
1304 debug_visitor_->OnReceiveCompressedFrame(
1305 current_frame_stream_id_,
1306 current_frame_type_,
1307 current_frame_length_);
1309 visitor_->OnSynStream(
1310 current_frame_stream_id_,
1311 associated_to_stream_id,
1312 priority,
1313 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1314 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
1316 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1317 break;
1318 case SETTINGS:
1319 if (protocol_version() > SPDY3 &&
1320 current_frame_flags_ & SETTINGS_FLAG_ACK) {
1321 visitor_->OnSettingsAck();
1322 CHANGE_STATE(SPDY_AUTO_RESET);
1323 } else {
1324 visitor_->OnSettings(current_frame_flags_ &
1325 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
1326 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
1328 break;
1329 case SYN_REPLY:
1330 case HEADERS:
1331 // SYN_REPLY and HEADERS are the same, save for the visitor call.
1333 if (protocol_version() > SPDY3) {
1334 DCHECK_EQ(HEADERS, current_frame_type_);
1336 bool successful_read = true;
1337 if (protocol_version() <= SPDY3) {
1338 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1339 DCHECK(successful_read);
1341 if (current_frame_stream_id_ == 0) {
1342 set_error(SPDY_INVALID_CONTROL_FRAME);
1343 break;
1345 if (protocol_version() <= SPDY2) {
1346 // SPDY 2 had two unused bytes here. Seek past them.
1347 reader.Seek(2);
1349 if (protocol_version() > SPDY3 &&
1350 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
1351 current_frame_type_ == HEADERS) {
1352 expect_continuation_ = current_frame_stream_id_;
1353 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
1355 const bool has_priority =
1356 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
1357 uint32 priority = 0;
1358 if (protocol_version() > SPDY3 && has_priority) {
1359 successful_read = reader.ReadUInt31(&priority);
1360 DCHECK(successful_read);
1362 DCHECK(reader.IsDoneReading());
1363 if (debug_visitor_) {
1364 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
1365 SpdyFrameType reported_type = current_frame_type_;
1366 if (protocol_version() > SPDY3 && has_priority) {
1367 reported_type = SYN_STREAM;
1369 debug_visitor_->OnReceiveCompressedFrame(
1370 current_frame_stream_id_,
1371 reported_type,
1372 current_frame_length_);
1374 if (current_frame_type_ == SYN_REPLY) {
1375 visitor_->OnSynReply(
1376 current_frame_stream_id_,
1377 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
1378 } else if (protocol_version() > SPDY3 &&
1379 current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
1380 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes
1381 // can be made independent of wire changes.
1382 visitor_->OnSynStream(
1383 current_frame_stream_id_,
1384 0, // associated_to_stream_id
1385 priority,
1386 current_frame_flags_ & CONTROL_FLAG_FIN,
1387 false); // unidirectional
1388 } else {
1389 visitor_->OnHeaders(
1390 current_frame_stream_id_,
1391 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1392 expect_continuation_ == 0);
1395 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1396 break;
1397 case PUSH_PROMISE:
1399 DCHECK_LT(SPDY3, protocol_version());
1400 if (current_frame_stream_id_ == 0) {
1401 set_error(SPDY_INVALID_CONTROL_FRAME);
1402 break;
1404 SpdyStreamId promised_stream_id = kInvalidStream;
1405 bool successful_read = reader.ReadUInt31(&promised_stream_id);
1406 DCHECK(successful_read);
1407 DCHECK(reader.IsDoneReading());
1408 if (promised_stream_id == 0) {
1409 set_error(SPDY_INVALID_CONTROL_FRAME);
1410 break;
1412 if (!(current_frame_flags_ & PUSH_PROMISE_FLAG_END_PUSH_PROMISE)) {
1413 expect_continuation_ = current_frame_stream_id_;
1415 if (debug_visitor_) {
1416 debug_visitor_->OnReceiveCompressedFrame(
1417 current_frame_stream_id_,
1418 current_frame_type_,
1419 current_frame_length_);
1421 visitor_->OnPushPromise(current_frame_stream_id_,
1422 promised_stream_id,
1423 (current_frame_flags_ &
1424 PUSH_PROMISE_FLAG_END_PUSH_PROMISE) != 0);
1426 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1427 break;
1428 case CONTINUATION:
1430 // Check to make sure the stream id of the current frame is
1431 // the same as that of the preceding frame.
1432 // If we're at this point we should already know that
1433 // expect_continuation_ != 0, so this doubles as a check
1434 // that current_frame_stream_id != 0.
1435 if (current_frame_stream_id_ != expect_continuation_) {
1436 set_error(SPDY_INVALID_CONTROL_FRAME);
1437 break;
1439 if (current_frame_flags_ & HEADERS_FLAG_END_HEADERS) {
1440 expect_continuation_ = 0;
1442 if (debug_visitor_) {
1443 debug_visitor_->OnReceiveCompressedFrame(
1444 current_frame_stream_id_,
1445 current_frame_type_,
1446 current_frame_length_);
1448 visitor_->OnContinuation(current_frame_stream_id_,
1449 (current_frame_flags_ &
1450 HEADERS_FLAG_END_HEADERS) != 0);
1452 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1453 break;
1454 default:
1455 DCHECK(false);
1458 return original_len - len;
1461 // Does not buffer the control payload. Instead, either passes directly to the
1462 // visitor or decompresses and then passes directly to the visitor, via
1463 // IncrementallyDeliverControlFrameHeaderData() or
1464 // IncrementallyDecompressControlFrameHeaderData() respectively.
1465 size_t SpdyFramer::ProcessControlFrameHeaderBlock(const char* data,
1466 size_t data_len,
1467 bool is_hpack_header_block) {
1468 DCHECK_EQ(SPDY_CONTROL_FRAME_HEADER_BLOCK, state_);
1470 bool processed_successfully = true;
1471 if (current_frame_type_ != SYN_STREAM &&
1472 current_frame_type_ != SYN_REPLY &&
1473 current_frame_type_ != HEADERS &&
1474 current_frame_type_ != PUSH_PROMISE &&
1475 current_frame_type_ != CONTINUATION) {
1476 LOG(DFATAL) << "Unhandled frame type in ProcessControlFrameHeaderBlock.";
1478 size_t process_bytes = std::min(data_len, remaining_data_length_);
1479 if (is_hpack_header_block) {
1480 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_,
1481 data,
1482 process_bytes)) {
1483 // TODO(jgraettinger): Finer-grained HPACK error codes.
1484 set_error(SPDY_DECOMPRESS_FAILURE);
1485 processed_successfully = false;
1487 } else if (process_bytes > 0) {
1488 if (enable_compression_ && protocol_version() <= SPDY3) {
1489 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1490 current_frame_stream_id_, data, process_bytes);
1491 } else {
1492 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1493 current_frame_stream_id_, data, process_bytes);
1496 remaining_data_length_ -= process_bytes;
1498 // Handle the case that there is no futher data in this frame.
1499 if (remaining_data_length_ == 0 && processed_successfully) {
1500 if (expect_continuation_ == 0) {
1501 if (is_hpack_header_block) {
1502 if (!hpack_decoder_.HandleControlFrameHeadersComplete(
1503 current_frame_stream_id_)) {
1504 set_error(SPDY_DECOMPRESS_FAILURE);
1505 processed_successfully = false;
1506 } else {
1507 // TODO(jgraettinger): To be removed with migration to
1508 // SpdyHeadersHandlerInterface. Serializes the HPACK block as a SPDY3
1509 // block, delivered via reentrant call to
1510 // ProcessControlFrameHeaderBlock().
1511 DeliverHpackBlockAsSpdy3Block();
1512 return process_bytes;
1514 } else {
1515 // The complete header block has been delivered. We send a zero-length
1516 // OnControlFrameHeaderData() to indicate this.
1517 visitor_->OnControlFrameHeaderData(current_frame_stream_id_, NULL, 0);
1519 // If this is a FIN, tell the caller.
1520 if ((current_frame_flags_ & CONTROL_FLAG_FIN) || end_stream_when_done_) {
1521 end_stream_when_done_ = false;
1522 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1525 if (processed_successfully)
1526 CHANGE_STATE(SPDY_AUTO_RESET);
1529 // Handle error.
1530 if (!processed_successfully) {
1531 return data_len;
1534 // Return amount processed.
1535 return process_bytes;
1538 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
1539 size_t data_len) {
1540 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
1541 DCHECK_EQ(SETTINGS, current_frame_type_);
1542 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
1543 size_t processed_bytes = 0;
1545 size_t setting_size = protocol_version() <= SPDY3 ? 8 : 5;
1547 // Loop over our incoming data.
1548 while (unprocessed_bytes > 0) {
1549 // Process up to one setting at a time.
1550 size_t processing = std::min(
1551 unprocessed_bytes,
1552 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len));
1554 // Check if we have a complete setting in our input.
1555 if (processing == setting_size) {
1556 // Parse the setting directly out of the input without buffering.
1557 if (!ProcessSetting(data + processed_bytes)) {
1558 set_error(SPDY_INVALID_CONTROL_FRAME);
1559 return processed_bytes;
1561 } else {
1562 // Continue updating settings_scratch_.setting_buf.
1563 memcpy(settings_scratch_.setting_buf + settings_scratch_.setting_buf_len,
1564 data + processed_bytes,
1565 processing);
1566 settings_scratch_.setting_buf_len += processing;
1568 // Check if we have a complete setting buffered.
1569 if (settings_scratch_.setting_buf_len == setting_size) {
1570 if (!ProcessSetting(settings_scratch_.setting_buf)) {
1571 set_error(SPDY_INVALID_CONTROL_FRAME);
1572 return processed_bytes;
1574 // Reset settings_scratch_.setting_buf for our next setting.
1575 settings_scratch_.setting_buf_len = 0;
1579 // Iterate.
1580 unprocessed_bytes -= processing;
1581 processed_bytes += processing;
1584 // Check if we're done handling this SETTINGS frame.
1585 remaining_data_length_ -= processed_bytes;
1586 if (remaining_data_length_ == 0) {
1587 visitor_->OnSettingsEnd();
1588 CHANGE_STATE(SPDY_AUTO_RESET);
1591 return processed_bytes;
1594 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1595 DCHECK_LT(SPDY3, protocol_version());
1596 DCHECK_EQ(0u, remaining_data_length_);
1598 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block();
1599 if (block.empty()) {
1600 // Special-case this to make tests happy.
1601 ProcessControlFrameHeaderBlock(NULL, 0, false);
1602 return;
1604 SpdyFrameBuilder builder(
1605 GetSerializedLength(protocol_version(), &block),
1606 SPDY3);
1608 SerializeNameValueBlockWithoutCompression(&builder, block);
1609 scoped_ptr<SpdyFrame> frame(builder.take());
1611 remaining_data_length_ = frame->size();
1612 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
1615 bool SpdyFramer::ProcessSetting(const char* data) {
1616 int id_field;
1617 SpdySettingsIds id;
1618 uint8 flags = 0;
1619 uint32 value;
1621 // Extract fields.
1622 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
1623 if (protocol_version() <= SPDY3) {
1624 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
1625 SettingsFlagsAndId id_and_flags =
1626 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire);
1627 id_field = id_and_flags.id();
1628 flags = id_and_flags.flags();
1629 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
1630 } else {
1631 id_field = *(reinterpret_cast<const uint8*>(data));
1632 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1)));
1635 // Validate id.
1636 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) {
1637 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field;
1638 return false;
1640 id = SpdyConstants::ParseSettingId(protocol_version(), id_field);
1642 if (protocol_version() <= SPDY3) {
1643 // Detect duplicates.
1644 if (id <= settings_scratch_.last_setting_id) {
1645 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
1646 << " in " << display_protocol_ << " SETTINGS frame "
1647 << "(last setting id was "
1648 << settings_scratch_.last_setting_id << ").";
1649 return false;
1651 settings_scratch_.last_setting_id = id;
1653 // Validate flags.
1654 uint8 kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED;
1655 if ((flags & ~(kFlagsMask)) != 0) {
1656 DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": "
1657 << flags;
1658 return false;
1662 // Validation succeeded. Pass on to visitor.
1663 visitor_->OnSetting(id, flags, value);
1664 return true;
1667 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) {
1668 size_t original_len = len;
1669 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len,
1670 remaining_data_length_);
1671 remaining_data_length_ -= bytes_read;
1672 if (remaining_data_length_ == 0) {
1673 SpdyFrameReader reader(current_frame_buffer_.get(),
1674 current_frame_buffer_length_);
1675 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header.
1677 // Use frame-specific handlers.
1678 switch (current_frame_type_) {
1679 case PING: {
1680 SpdyPingId id = 0;
1681 bool is_ack = protocol_version() > SPDY3 &&
1682 (current_frame_flags_ & PING_FLAG_ACK);
1683 bool successful_read = true;
1684 if (protocol_version() <= SPDY3) {
1685 uint32 id32 = 0;
1686 successful_read = reader.ReadUInt32(&id32);
1687 id = id32;
1688 } else {
1689 successful_read = reader.ReadUInt64(&id);
1691 DCHECK(successful_read);
1692 DCHECK(reader.IsDoneReading());
1693 visitor_->OnPing(id, is_ack);
1695 break;
1696 case WINDOW_UPDATE: {
1697 uint32 delta_window_size = 0;
1698 bool successful_read = true;
1699 if (protocol_version() <= SPDY3) {
1700 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1701 DCHECK(successful_read);
1703 successful_read = reader.ReadUInt32(&delta_window_size);
1704 DCHECK(successful_read);
1705 DCHECK(reader.IsDoneReading());
1706 visitor_->OnWindowUpdate(current_frame_stream_id_,
1707 delta_window_size);
1709 break;
1710 case BLOCKED: {
1711 DCHECK_LT(SPDY3, protocol_version());
1712 DCHECK(reader.IsDoneReading());
1713 visitor_->OnBlocked(current_frame_stream_id_);
1715 break;
1716 default:
1717 // Unreachable.
1718 LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
1721 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
1723 return original_len - len;
1726 size_t SpdyFramer::ProcessGoAwayFramePayload(const char* data, size_t len) {
1727 if (len == 0) {
1728 return 0;
1730 // Clamp to the actual remaining payload.
1731 if (len > remaining_data_length_) {
1732 len = remaining_data_length_;
1734 size_t original_len = len;
1736 // Check if we had already read enough bytes to parse the GOAWAY header.
1737 const size_t header_size = GetGoAwayMinimumSize();
1738 size_t unread_header_bytes = header_size - current_frame_buffer_length_;
1739 bool already_parsed_header = (unread_header_bytes == 0);
1740 if (!already_parsed_header) {
1741 // Buffer the new GOAWAY header bytes we got.
1742 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);
1744 // Do we have enough to parse the constant size GOAWAY header?
1745 if (current_frame_buffer_length_ == header_size) {
1746 // Parse out the last good stream id.
1747 SpdyFrameReader reader(current_frame_buffer_.get(),
1748 current_frame_buffer_length_);
1749 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1750 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1751 DCHECK(successful_read);
1753 // In SPDYv3 and up, frames also specify a status code - parse it out.
1754 SpdyGoAwayStatus status = GOAWAY_OK;
1755 if (protocol_version() >= SPDY3) {
1756 uint32 status_raw = GOAWAY_OK;
1757 successful_read = reader.ReadUInt32(&status_raw);
1758 DCHECK(successful_read);
1759 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(),
1760 status_raw)) {
1761 status = SpdyConstants::ParseGoAwayStatus(protocol_version(),
1762 status_raw);
1763 } else {
1764 DCHECK(false);
1765 // Throw an error for SPDY4+, keep liberal behavior
1766 // for earlier versions.
1767 if (protocol_version() > SPDY3) {
1768 DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw;
1769 set_error(SPDY_INVALID_CONTROL_FRAME);
1770 return 0;
1774 // Finished parsing the GOAWAY header, call frame handler.
1775 visitor_->OnGoAway(current_frame_stream_id_, status);
1779 // Handle remaining data as opaque.
1780 bool processed_successfully = true;
1781 if (len > 0) {
1782 processed_successfully = visitor_->OnGoAwayFrameData(data, len);
1784 remaining_data_length_ -= original_len;
1785 if (!processed_successfully) {
1786 set_error(SPDY_GOAWAY_FRAME_CORRUPT);
1787 } else if (remaining_data_length_ == 0) {
1788 // Signal that there is not more opaque data.
1789 visitor_->OnGoAwayFrameData(NULL, 0);
1790 CHANGE_STATE(SPDY_AUTO_RESET);
1792 return original_len;
1795 size_t SpdyFramer::ProcessRstStreamFramePayload(const char* data, size_t len) {
1796 if (len == 0) {
1797 return 0;
1799 // Clamp to the actual remaining payload.
1800 if (len > remaining_data_length_) {
1801 len = remaining_data_length_;
1803 size_t original_len = len;
1805 // Check if we had already read enough bytes to parse the fixed-length portion
1806 // of the RST_STREAM frame.
1807 const size_t header_size = GetRstStreamMinimumSize();
1808 size_t unread_header_bytes = header_size - current_frame_buffer_length_;
1809 bool already_parsed_header = (unread_header_bytes == 0);
1810 if (!already_parsed_header) {
1811 // Buffer the new RST_STREAM header bytes we got.
1812 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);
1814 // Do we have enough to parse the constant size RST_STREAM header?
1815 if (current_frame_buffer_length_ == header_size) {
1816 // Parse out the last good stream id.
1817 SpdyFrameReader reader(current_frame_buffer_.get(),
1818 current_frame_buffer_length_);
1819 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1820 if (protocol_version() <= SPDY3) {
1821 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1822 DCHECK(successful_read);
1825 SpdyRstStreamStatus status = RST_STREAM_INVALID;
1826 uint32 status_raw = status;
1827 bool successful_read = reader.ReadUInt32(&status_raw);
1828 DCHECK(successful_read);
1829 if (SpdyConstants::IsValidRstStreamStatus(protocol_version(),
1830 status_raw)) {
1831 status = static_cast<SpdyRstStreamStatus>(status_raw);
1832 } else {
1833 // Throw an error for SPDY4+, keep liberal behavior
1834 // for earlier versions.
1835 if (protocol_version() > SPDY3) {
1836 DLOG(WARNING) << "Invalid RST_STREAM status " << status_raw;
1837 set_error(SPDY_INVALID_CONTROL_FRAME);
1838 return 0;
1841 // Finished parsing the RST_STREAM header, call frame handler.
1842 visitor_->OnRstStream(current_frame_stream_id_, status);
1846 // Handle remaining data as opaque.
1847 bool processed_successfully = true;
1848 if (len > 0) {
1849 processed_successfully = visitor_->OnRstStreamFrameData(data, len);
1851 remaining_data_length_ -= original_len;
1852 if (!processed_successfully) {
1853 set_error(SPDY_RST_STREAM_FRAME_CORRUPT);
1854 } else if (remaining_data_length_ == 0) {
1855 // Signal that there is not more opaque data.
1856 visitor_->OnRstStreamFrameData(NULL, 0);
1857 CHANGE_STATE(SPDY_AUTO_RESET);
1859 return original_len;
1862 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
1863 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
1865 size_t original_len = len;
1866 if (remaining_padding_length_fields_ == 0) {
1867 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1868 bool pad_low = false;
1869 bool pad_high = false;
1870 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) {
1871 pad_low = true;
1872 ++remaining_padding_length_fields_;
1874 if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) {
1875 pad_high = true;
1876 ++remaining_padding_length_fields_;
1878 if ((pad_high && !pad_low) ||
1879 remaining_data_length_ < remaining_padding_length_fields_) {
1880 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1881 return 0;
1885 // Parse the padding length.
1886 while (len != 0 && remaining_padding_length_fields_ != 0) {
1887 remaining_padding_payload_length_ =
1888 (remaining_padding_payload_length_ << 8) +
1889 *reinterpret_cast<const uint8*>(data);
1890 ++data;
1891 --len;
1892 --remaining_padding_length_fields_;
1893 --remaining_data_length_;
1896 if (remaining_padding_length_fields_ == 0) {
1897 if (remaining_padding_payload_length_ > remaining_data_length_) {
1898 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1899 return 0;
1901 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
1903 return original_len - len;
1906 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
1907 DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
1909 size_t original_len = len;
1910 if (remaining_padding_payload_length_ > 0) {
1911 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
1912 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
1913 // The visitor needs to know about padding so it can send window updates.
1914 // Communicate the padding to the visitor through a NULL data pointer, with
1915 // a nonzero size.
1916 if (amount_to_discard) {
1917 visitor_->OnStreamFrameData(
1918 current_frame_stream_id_, NULL, amount_to_discard, false);
1920 data += amount_to_discard;
1921 len -= amount_to_discard;
1922 remaining_padding_payload_length_ -= amount_to_discard;
1923 remaining_data_length_ -= amount_to_discard;
1926 if (remaining_data_length_ == 0) {
1927 // If the FIN flag is set, and there is no more data in this data frame,
1928 // inform the visitor of EOF via a 0-length data frame.
1929 if (current_frame_flags_ & DATA_FLAG_FIN) {
1930 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1933 CHANGE_STATE(SPDY_AUTO_RESET);
1935 return original_len - len;
1938 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
1939 size_t original_len = len;
1940 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
1941 size_t amount_to_forward = std::min(
1942 remaining_data_length_ - remaining_padding_payload_length_, len);
1943 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
1944 // Only inform the visitor if there is data.
1945 if (amount_to_forward) {
1946 visitor_->OnStreamFrameData(
1947 current_frame_stream_id_, data, amount_to_forward, false);
1950 data += amount_to_forward;
1951 len -= amount_to_forward;
1952 remaining_data_length_ -= amount_to_forward;
1955 if (remaining_data_length_ == remaining_padding_payload_length_) {
1956 CHANGE_STATE(SPDY_CONSUME_PADDING);
1958 return original_len - len;
1961 size_t SpdyFramer::ProcessIgnoredControlFramePayload(/*const char* data,*/
1962 size_t len) {
1963 size_t original_len = len;
1964 if (remaining_data_length_ > 0) {
1965 size_t amount_to_ignore = std::min(remaining_data_length_, len);
1966 len -= amount_to_ignore;
1967 remaining_data_length_ -= amount_to_ignore;
1970 if (remaining_data_length_ == 0) {
1971 CHANGE_STATE(SPDY_AUTO_RESET);
1973 return original_len - len;
1976 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
1977 size_t header_length,
1978 SpdyHeaderBlock* block) const {
1979 SpdyFrameReader reader(header_data, header_length);
1981 // Read number of headers.
1982 uint32 num_headers;
1983 if (protocol_version() <= SPDY2) {
1984 uint16 temp;
1985 if (!reader.ReadUInt16(&temp)) {
1986 DVLOG(1) << "Unable to read number of headers.";
1987 return 0;
1989 num_headers = temp;
1990 } else {
1991 if (!reader.ReadUInt32(&num_headers)) {
1992 DVLOG(1) << "Unable to read number of headers.";
1993 return 0;
1997 // Read each header.
1998 for (uint32 index = 0; index < num_headers; ++index) {
1999 base::StringPiece temp;
2001 // Read header name.
2002 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
2003 : !reader.ReadStringPiece32(&temp)) {
2004 DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
2005 << num_headers << ").";
2006 return 0;
2008 std::string name = temp.as_string();
2010 // Read header value.
2011 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
2012 : !reader.ReadStringPiece32(&temp)) {
2013 DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
2014 << num_headers << ").";
2015 return 0;
2017 std::string value = temp.as_string();
2019 // Ensure no duplicates.
2020 if (block->find(name) != block->end()) {
2021 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of "
2022 << num_headers << ").";
2023 return 0;
2026 // Store header.
2027 (*block)[name] = value;
2029 return reader.GetBytesConsumed();
2032 SpdySerializedFrame* SpdyFramer::SerializeData(
2033 const SpdyDataIR& data_ir) const {
2034 uint8 flags = DATA_FLAG_NONE;
2035 if (data_ir.fin()) {
2036 flags = DATA_FLAG_FIN;
2039 if (protocol_version() > SPDY3) {
2040 int num_padding_fields = 0;
2041 if (data_ir.pad_low()) {
2042 flags |= DATA_FLAG_PAD_LOW;
2043 ++num_padding_fields;
2045 if (data_ir.pad_high()) {
2046 flags |= DATA_FLAG_PAD_HIGH;
2047 ++num_padding_fields;
2050 const size_t size_with_padding = num_padding_fields +
2051 data_ir.data().length() + data_ir.padding_payload_len() +
2052 GetDataFrameMinimumSize();
2053 SpdyFrameBuilder builder(size_with_padding, protocol_version());
2054 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2055 if (data_ir.pad_high()) {
2056 builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
2058 if (data_ir.pad_low()) {
2059 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2061 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
2062 if (data_ir.padding_payload_len() > 0) {
2063 string padding = string(data_ir.padding_payload_len(), '0');
2064 builder.WriteBytes(padding.data(), padding.length());
2066 DCHECK_EQ(size_with_padding, builder.length());
2067 return builder.take();
2068 } else {
2069 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length();
2070 SpdyFrameBuilder builder(size, protocol_version());
2071 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2072 builder.WriteBytes(data_ir.data().data(), data_ir.data().length());
2073 DCHECK_EQ(size, builder.length());
2074 return builder.take();
2078 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
2079 const SpdyDataIR& data_ir) const {
2080 uint8 flags = DATA_FLAG_NONE;
2081 if (data_ir.fin()) {
2082 flags = DATA_FLAG_FIN;
2085 size_t frame_size = GetDataFrameMinimumSize();
2086 size_t num_padding_fields = 0;
2087 if (protocol_version() > SPDY3) {
2088 if (data_ir.pad_low()) {
2089 flags |= DATA_FLAG_PAD_LOW;
2090 ++num_padding_fields;
2092 if (data_ir.pad_high()) {
2093 flags |= DATA_FLAG_PAD_HIGH;
2094 ++num_padding_fields;
2096 frame_size += num_padding_fields;
2099 SpdyFrameBuilder builder(frame_size, protocol_version());
2100 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags);
2101 if (protocol_version() > SPDY3) {
2102 if (data_ir.pad_high()) {
2103 builder.WriteUInt8(data_ir.padding_payload_len() >> 8);
2105 if (data_ir.pad_low()) {
2106 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2108 builder.OverwriteLength(*this, num_padding_fields +
2109 data_ir.data().length() + data_ir.padding_payload_len());
2110 } else {
2111 builder.OverwriteLength(*this, data_ir.data().length());
2113 DCHECK_EQ(frame_size, builder.length());
2114 return builder.take();
2117 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
2118 const SpdySynStreamIR& syn_stream) {
2119 uint8 flags = 0;
2120 if (syn_stream.fin()) {
2121 flags |= CONTROL_FLAG_FIN;
2123 if (syn_stream.unidirectional()) {
2124 // TODO(hkhalil): invalid for HTTP2.
2125 flags |= CONTROL_FLAG_UNIDIRECTIONAL;
2127 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now
2128 // we never expect to have to overflow into a CONTINUATION frame.
2129 if (protocol_version() > SPDY3) {
2130 flags |= HEADERS_FLAG_PRIORITY;
2131 flags |= HEADERS_FLAG_END_HEADERS;
2134 // Sanitize priority.
2135 uint8 priority = syn_stream.priority();
2136 if (priority > GetLowestPriority()) {
2137 DLOG(DFATAL) << "Priority out-of-bounds.";
2138 priority = GetLowestPriority();
2141 // The size of this frame, including variable-length name-value block.
2142 size_t size = GetSynStreamMinimumSize();
2144 string hpack_encoding;
2145 if (protocol_version() > SPDY3) {
2146 if (enable_compression_) {
2147 hpack_encoder_.EncodeHeaderSet(
2148 syn_stream.name_value_block(), &hpack_encoding);
2149 } else {
2150 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2151 syn_stream.name_value_block(), &hpack_encoding);
2153 size += hpack_encoding.size();
2154 } else {
2155 size += GetSerializedLength(syn_stream.name_value_block());
2158 SpdyFrameBuilder builder(size, protocol_version());
2159 if (protocol_version() <= SPDY3) {
2160 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
2161 builder.WriteUInt32(syn_stream.stream_id());
2162 builder.WriteUInt32(syn_stream.associated_to_stream_id());
2163 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
2164 builder.WriteUInt8(0); // Unused byte where credential slot used to be.
2165 } else {
2166 builder.BeginNewFrame(*this,
2167 HEADERS,
2168 flags,
2169 syn_stream.stream_id());
2170 builder.WriteUInt32(priority);
2172 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
2173 if (protocol_version() > SPDY3) {
2174 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2175 } else {
2176 SerializeNameValueBlock(&builder, syn_stream);
2179 if (debug_visitor_) {
2180 const size_t payload_len = protocol_version() > SPDY3 ?
2181 hpack_encoding.size() :
2182 GetSerializedLength(protocol_version(),
2183 &(syn_stream.name_value_block()));
2184 // SPDY 4 reports this compression as a SYN_STREAM compression.
2185 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
2186 SYN_STREAM,
2187 payload_len,
2188 builder.length());
2191 return builder.take();
2194 SpdySerializedFrame* SpdyFramer::SerializeSynReply(
2195 const SpdySynReplyIR& syn_reply) {
2196 uint8 flags = 0;
2197 if (syn_reply.fin()) {
2198 flags |= CONTROL_FLAG_FIN;
2200 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now
2201 // we never expect to have to overflow into a CONTINUATION frame.
2202 if (protocol_version() > SPDY3) {
2203 flags |= HEADERS_FLAG_END_HEADERS;
2206 // The size of this frame, including variable-length name-value block.
2207 size_t size = GetSynReplyMinimumSize();
2209 string hpack_encoding;
2210 if (protocol_version() > SPDY3) {
2211 if (enable_compression_) {
2212 hpack_encoder_.EncodeHeaderSet(
2213 syn_reply.name_value_block(), &hpack_encoding);
2214 } else {
2215 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2216 syn_reply.name_value_block(), &hpack_encoding);
2218 size += hpack_encoding.size();
2219 } else {
2220 size += GetSerializedLength(syn_reply.name_value_block());
2223 SpdyFrameBuilder builder(size, protocol_version());
2224 if (protocol_version() <= SPDY3) {
2225 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
2226 builder.WriteUInt32(syn_reply.stream_id());
2227 } else {
2228 builder.BeginNewFrame(*this,
2229 HEADERS,
2230 flags,
2231 syn_reply.stream_id());
2233 if (protocol_version() < SPDY3) {
2234 builder.WriteUInt16(0); // Unused.
2236 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
2237 if (protocol_version() > SPDY3) {
2238 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2239 } else {
2240 SerializeNameValueBlock(&builder, syn_reply);
2243 if (debug_visitor_) {
2244 const size_t payload_len = protocol_version() > SPDY3 ?
2245 hpack_encoding.size() :
2246 GetSerializedLength(protocol_version(),
2247 &(syn_reply.name_value_block()));
2248 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
2249 SYN_REPLY,
2250 payload_len,
2251 builder.length());
2254 return builder.take();
2257 SpdySerializedFrame* SpdyFramer::SerializeRstStream(
2258 const SpdyRstStreamIR& rst_stream) const {
2259 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
2260 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
2261 // which doesn't currently include RST_STREAM payloads. GFE flags have been
2262 // commented but left in place to simplify future patching.
2263 // Compute the output buffer size, taking opaque data into account.
2264 uint16 expected_length = GetRstStreamMinimumSize();
2265 if (protocol_version() > SPDY3) {
2266 expected_length += rst_stream.description().size();
2268 SpdyFrameBuilder builder(expected_length, protocol_version());
2270 // Serialize the RST_STREAM frame.
2271 if (protocol_version() <= SPDY3) {
2272 builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
2273 builder.WriteUInt32(rst_stream.stream_id());
2274 } else {
2275 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
2278 builder.WriteUInt32(rst_stream.status());
2280 // In SPDY4 and up, RST_STREAM frames may also specify opaque data.
2281 if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
2282 builder.WriteBytes(rst_stream.description().data(),
2283 rst_stream.description().size());
2286 DCHECK_EQ(expected_length, builder.length());
2287 return builder.take();
2290 SpdySerializedFrame* SpdyFramer::SerializeSettings(
2291 const SpdySettingsIR& settings) const {
2292 uint8 flags = 0;
2294 if (protocol_version() <= SPDY3) {
2295 if (settings.clear_settings()) {
2296 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
2298 } else {
2299 if (settings.is_ack()) {
2300 flags |= SETTINGS_FLAG_ACK;
2303 const SpdySettingsIR::ValueMap* values = &(settings.values());
2305 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
2306 // Size, in bytes, of this SETTINGS frame.
2307 const size_t size = GetSettingsMinimumSize() +
2308 (values->size() * setting_size);
2309 SpdyFrameBuilder builder(size, protocol_version());
2310 if (protocol_version() <= SPDY3) {
2311 builder.WriteControlFrameHeader(*this, SETTINGS, flags);
2312 } else {
2313 builder.BeginNewFrame(*this, SETTINGS, flags, 0);
2316 // If this is an ACK, payload should be empty.
2317 if (protocol_version() > SPDY3 && settings.is_ack()) {
2318 return builder.take();
2321 if (protocol_version() <= SPDY3) {
2322 builder.WriteUInt32(values->size());
2324 DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
2325 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
2326 it != values->end();
2327 ++it) {
2328 if (protocol_version() <= SPDY3) {
2329 uint8 setting_flags = 0;
2330 if (it->second.persist_value) {
2331 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
2333 if (it->second.persisted) {
2334 setting_flags |= SETTINGS_FLAG_PERSISTED;
2336 SettingsFlagsAndId flags_and_id(
2337 setting_flags,
2338 SpdyConstants::SerializeSettingId(protocol_version(), it->first));
2339 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
2340 builder.WriteBytes(&id_and_flags_wire, 4);
2341 } else {
2342 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(),
2343 it->first));
2345 builder.WriteUInt32(it->second.value);
2347 DCHECK_EQ(size, builder.length());
2348 return builder.take();
2351 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
2352 SpdyFrameBuilder builder(GetPingSize(), protocol_version());
2353 if (protocol_version() <= SPDY3) {
2354 builder.WriteControlFrameHeader(*this, PING, kNoFlags);
2355 builder.WriteUInt32(static_cast<uint32>(ping.id()));
2356 } else {
2357 uint8 flags = 0;
2358 if (ping.is_ack()) {
2359 flags |= PING_FLAG_ACK;
2361 builder.BeginNewFrame(*this, PING, flags, 0);
2362 builder.WriteUInt64(ping.id());
2364 DCHECK_EQ(GetPingSize(), builder.length());
2365 return builder.take();
2368 SpdySerializedFrame* SpdyFramer::SerializeGoAway(
2369 const SpdyGoAwayIR& goaway) const {
2371 // Compute the output buffer size, take opaque data into account.
2372 uint16 expected_length = GetGoAwayMinimumSize();
2373 if (protocol_version() > SPDY3) {
2374 expected_length += goaway.description().size();
2376 SpdyFrameBuilder builder(expected_length, protocol_version());
2378 // Serialize the GOAWAY frame.
2379 if (protocol_version() <= SPDY3) {
2380 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
2381 } else {
2382 builder.BeginNewFrame(*this, GOAWAY, 0, 0);
2385 // GOAWAY frames specify the last good stream id for all SPDY versions.
2386 builder.WriteUInt32(goaway.last_good_stream_id());
2388 // In SPDY3 and up, GOAWAY frames also specify the error status code.
2389 if (protocol_version() >= SPDY3) {
2390 builder.WriteUInt32(goaway.status());
2393 // In SPDY4 and up, GOAWAY frames may also specify opaque data.
2394 if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) {
2395 builder.WriteBytes(goaway.description().data(),
2396 goaway.description().size());
2399 DCHECK_EQ(expected_length, builder.length());
2400 return builder.take();
2403 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
2404 const SpdyHeadersIR& headers) {
2405 uint8 flags = 0;
2406 if (headers.fin()) {
2407 flags |= CONTROL_FLAG_FIN;
2409 if (protocol_version() > SPDY3) {
2410 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will
2411 // get overwritten below, so we should probably just get rid of the
2412 // end_headers field.
2413 if (headers.end_headers()) {
2414 flags |= HEADERS_FLAG_END_HEADERS;
2416 if (headers.has_priority()) {
2417 flags |= HEADERS_FLAG_PRIORITY;
2421 // The size of this frame, including variable-length name-value block.
2422 size_t size = GetHeadersMinimumSize();
2424 uint32 priority = headers.priority();
2425 if (headers.has_priority()) {
2426 if (priority > GetLowestPriority()) {
2427 DLOG(DFATAL) << "Priority out-of-bounds.";
2428 priority = GetLowestPriority();
2430 size += 4;
2433 string hpack_encoding;
2434 if (protocol_version() > SPDY3) {
2435 if (enable_compression_) {
2436 hpack_encoder_.EncodeHeaderSet(
2437 headers.name_value_block(), &hpack_encoding);
2438 } else {
2439 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2440 headers.name_value_block(), &hpack_encoding);
2442 size += hpack_encoding.size();
2443 if (size > GetControlFrameBufferMaxSize()) {
2444 size += GetNumberRequiredContinuationFrames(size) *
2445 GetContinuationMinimumSize();
2446 flags &= ~HEADERS_FLAG_END_HEADERS;
2448 } else {
2449 size += GetSerializedLength(headers.name_value_block());
2452 SpdyFrameBuilder builder(size, protocol_version());
2453 if (protocol_version() <= SPDY3) {
2454 builder.WriteControlFrameHeader(*this, HEADERS, flags);
2455 builder.WriteUInt32(headers.stream_id());
2456 } else {
2457 builder.BeginNewFrame(*this,
2458 HEADERS,
2459 flags,
2460 headers.stream_id());
2461 if (headers.has_priority()) {
2462 builder.WriteUInt32(priority);
2465 if (protocol_version() <= SPDY2) {
2466 builder.WriteUInt16(0); // Unused.
2468 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2470 if (protocol_version() > SPDY3) {
2471 WritePayloadWithContinuation(&builder,
2472 hpack_encoding,
2473 headers.stream_id(),
2474 HEADERS);
2475 } else {
2476 SerializeNameValueBlock(&builder, headers);
2479 if (debug_visitor_) {
2480 const size_t payload_len = protocol_version() > SPDY3 ?
2481 hpack_encoding.size() :
2482 GetSerializedLength(protocol_version(),
2483 &(headers.name_value_block()));
2484 debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
2485 HEADERS,
2486 payload_len,
2487 builder.length());
2490 return builder.take();
2493 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
2494 const SpdyWindowUpdateIR& window_update) const {
2495 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version());
2496 if (protocol_version() <= SPDY3) {
2497 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
2498 builder.WriteUInt32(window_update.stream_id());
2499 } else {
2500 builder.BeginNewFrame(*this,
2501 WINDOW_UPDATE,
2502 kNoFlags,
2503 window_update.stream_id());
2505 builder.WriteUInt32(window_update.delta());
2506 DCHECK_EQ(GetWindowUpdateSize(), builder.length());
2507 return builder.take();
2510 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
2511 DCHECK_LT(SPDY3, protocol_version());
2512 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version());
2513 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2514 return builder.take();
2517 SpdyFrame* SpdyFramer::SerializePushPromise(
2518 const SpdyPushPromiseIR& push_promise) {
2519 DCHECK_LT(SPDY3, protocol_version());
2520 uint8 flags = 0;
2521 // TODO(mlavan): If we overflow into a CONTINUATION frame, this will
2522 // get overwritten below, so we should probably just get rid of the
2523 // end_push_promise field.
2524 if (push_promise.end_push_promise()) {
2525 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2527 // The size of this frame, including variable-length name-value block.
2528 size_t size = GetPushPromiseMinimumSize();
2530 string hpack_encoding;
2531 if (protocol_version() > SPDY3) {
2532 if (enable_compression_) {
2533 hpack_encoder_.EncodeHeaderSet(
2534 push_promise.name_value_block(), &hpack_encoding);
2535 } else {
2536 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2537 push_promise.name_value_block(), &hpack_encoding);
2539 size += hpack_encoding.size();
2540 if (size > GetControlFrameBufferMaxSize()) {
2541 size += GetNumberRequiredContinuationFrames(size) *
2542 GetContinuationMinimumSize();
2543 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2545 } else {
2546 size += GetSerializedLength(push_promise.name_value_block());
2549 SpdyFrameBuilder builder(size, protocol_version());
2550 builder.BeginNewFrame(*this,
2551 PUSH_PROMISE,
2552 flags,
2553 push_promise.stream_id());
2554 builder.WriteUInt32(push_promise.promised_stream_id());
2555 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
2557 if (protocol_version() > SPDY3) {
2558 WritePayloadWithContinuation(&builder,
2559 hpack_encoding,
2560 push_promise.stream_id(),
2561 PUSH_PROMISE);
2562 } else {
2563 SerializeNameValueBlock(&builder, push_promise);
2566 if (debug_visitor_) {
2567 const size_t payload_len = protocol_version() > SPDY3 ?
2568 hpack_encoding.size() :
2569 GetSerializedLength(protocol_version(),
2570 &(push_promise.name_value_block()));
2571 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
2572 PUSH_PROMISE, payload_len, builder.length());
2575 return builder.take();
2578 // TODO(jgraettinger): This implementation is incorrect. The continuation
2579 // frame continues a previously-begun HPACK encoding; it doesn't begin a
2580 // new one. Figure out whether it makes sense to keep SerializeContinuation().
2581 SpdyFrame* SpdyFramer::SerializeContinuation(
2582 const SpdyContinuationIR& continuation) {
2583 CHECK_LT(SPDY3, protocol_version());
2584 uint8 flags = 0;
2585 if (continuation.end_headers()) {
2586 flags |= HEADERS_FLAG_END_HEADERS;
2589 // The size of this frame, including variable-length name-value block.
2590 size_t size = GetContinuationMinimumSize();
2591 string hpack_encoding;
2592 if (enable_compression_) {
2593 hpack_encoder_.EncodeHeaderSet(
2594 continuation.name_value_block(), &hpack_encoding);
2595 } else {
2596 hpack_encoder_.EncodeHeaderSetWithoutCompression(
2597 continuation.name_value_block(), &hpack_encoding);
2599 size += hpack_encoding.size();
2601 SpdyFrameBuilder builder(size, protocol_version());
2602 builder.BeginNewFrame(*this, CONTINUATION, flags,
2603 continuation.stream_id());
2604 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2606 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2608 if (debug_visitor_) {
2609 const size_t payload_len = hpack_encoding.size();
2610 debug_visitor_->OnSendCompressedFrame(continuation.stream_id(),
2611 CONTINUATION, payload_len, builder.length());
2614 return builder.take();
2617 namespace {
2619 class FrameSerializationVisitor : public SpdyFrameVisitor {
2620 public:
2621 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {}
2622 virtual ~FrameSerializationVisitor() {}
2624 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); }
2626 virtual void VisitData(const SpdyDataIR& data) OVERRIDE {
2627 frame_.reset(framer_->SerializeData(data));
2629 virtual void VisitSynStream(const SpdySynStreamIR& syn_stream) OVERRIDE {
2630 frame_.reset(framer_->SerializeSynStream(syn_stream));
2632 virtual void VisitSynReply(const SpdySynReplyIR& syn_reply) OVERRIDE {
2633 frame_.reset(framer_->SerializeSynReply(syn_reply));
2635 virtual void VisitRstStream(const SpdyRstStreamIR& rst_stream) OVERRIDE {
2636 frame_.reset(framer_->SerializeRstStream(rst_stream));
2638 virtual void VisitSettings(const SpdySettingsIR& settings) OVERRIDE {
2639 frame_.reset(framer_->SerializeSettings(settings));
2641 virtual void VisitPing(const SpdyPingIR& ping) OVERRIDE {
2642 frame_.reset(framer_->SerializePing(ping));
2644 virtual void VisitGoAway(const SpdyGoAwayIR& goaway) OVERRIDE {
2645 frame_.reset(framer_->SerializeGoAway(goaway));
2647 virtual void VisitHeaders(const SpdyHeadersIR& headers) OVERRIDE {
2648 frame_.reset(framer_->SerializeHeaders(headers));
2650 virtual void VisitWindowUpdate(
2651 const SpdyWindowUpdateIR& window_update) OVERRIDE {
2652 frame_.reset(framer_->SerializeWindowUpdate(window_update));
2654 virtual void VisitBlocked(const SpdyBlockedIR& blocked) OVERRIDE {
2655 frame_.reset(framer_->SerializeBlocked(blocked));
2657 virtual void VisitPushPromise(
2658 const SpdyPushPromiseIR& push_promise) OVERRIDE {
2659 frame_.reset(framer_->SerializePushPromise(push_promise));
2661 virtual void VisitContinuation(
2662 const SpdyContinuationIR& continuation) OVERRIDE {
2663 frame_.reset(framer_->SerializeContinuation(continuation));
2666 private:
2667 SpdyFramer* framer_;
2668 scoped_ptr<SpdySerializedFrame> frame_;
2671 } // namespace
2673 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
2674 FrameSerializationVisitor visitor(this);
2675 frame.Visit(&visitor);
2676 return visitor.ReleaseSerializedFrame();
2679 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
2680 CHECK_GE(SPDY3, protocol_version());
2681 const size_t uncompressed_length =
2682 GetSerializedLength(protocol_version(), &headers);
2683 if (!enable_compression_) {
2684 return uncompressed_length;
2686 z_stream* compressor = GetHeaderCompressor();
2687 // Since we'll be performing lots of flushes when compressing the data,
2688 // zlib's lower bounds may be insufficient.
2689 return 2 * deflateBound(compressor, uncompressed_length);
2692 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
2693 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
2694 DCHECK_GT(protocol_version(), SPDY3);
2695 DCHECK_GT(size, kMaxControlFrameSize);
2696 size_t overflow = size - kMaxControlFrameSize;
2697 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
2700 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2701 const string& hpack_encoding,
2702 SpdyStreamId stream_id,
2703 SpdyFrameType type) {
2704 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
2706 // In addition to the prefix, fixed_field_size includes the size of
2707 // any fields that come before the variable-length name/value block.
2708 size_t fixed_field_size = 0;
2709 uint8 end_flag = 0;
2710 uint8 flags = 0;
2711 if (type == HEADERS) {
2712 fixed_field_size = GetHeadersMinimumSize();
2713 end_flag = HEADERS_FLAG_END_HEADERS;
2714 } else if (type == PUSH_PROMISE) {
2715 fixed_field_size = GetPushPromiseMinimumSize();
2716 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2717 } else {
2718 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
2719 << FrameTypeToString(type);
2722 // Write as much of the payload as possible into the initial frame.
2723 size_t bytes_remaining = hpack_encoding.size() -
2724 std::min(hpack_encoding.size(),
2725 kMaxControlFrameSize - fixed_field_size);
2726 builder->WriteBytes(&hpack_encoding[0],
2727 hpack_encoding.size() - bytes_remaining);
2729 if (bytes_remaining > 0) {
2730 builder->OverwriteLength(*this,
2731 kMaxControlFrameSize - GetControlFrameHeaderSize());
2734 // Tack on CONTINUATION frames for the overflow.
2735 while (bytes_remaining > 0) {
2736 size_t bytes_to_write = std::min(bytes_remaining,
2737 kMaxControlFrameSize -
2738 GetContinuationMinimumSize());
2739 // Write CONTINUATION frame prefix.
2740 if (bytes_remaining == bytes_to_write) {
2741 flags |= end_flag;
2743 builder->BeginNewFrame(*this,
2744 CONTINUATION,
2745 flags,
2746 stream_id);
2747 // Write payload fragment.
2748 builder->WriteBytes(&hpack_encoding[hpack_encoding.size() -
2749 bytes_remaining],
2750 bytes_to_write);
2751 bytes_remaining -= bytes_to_write;
2755 // The following compression setting are based on Brian Olson's analysis. See
2756 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac792
2757 // for more details.
2758 #if defined(USE_SYSTEM_ZLIB)
2759 // System zlib is not expected to have workaround for http://crbug.com/139744,
2760 // so disable compression in that case.
2761 // TODO(phajdan.jr): Remove the special case when it's no longer necessary.
2762 static const int kCompressorLevel = 0;
2763 #else // !defined(USE_SYSTEM_ZLIB)
2764 static const int kCompressorLevel = 9;
2765 #endif // !defined(USE_SYSTEM_ZLIB)
2766 static const int kCompressorWindowSizeInBits = 11;
2767 static const int kCompressorMemLevel = 1;
2769 z_stream* SpdyFramer::GetHeaderCompressor() {
2770 if (header_compressor_.get())
2771 return header_compressor_.get(); // Already initialized.
2773 header_compressor_.reset(new z_stream);
2774 memset(header_compressor_.get(), 0, sizeof(z_stream));
2776 int success = deflateInit2(header_compressor_.get(),
2777 kCompressorLevel,
2778 Z_DEFLATED,
2779 kCompressorWindowSizeInBits,
2780 kCompressorMemLevel,
2781 Z_DEFAULT_STRATEGY);
2782 if (success == Z_OK) {
2783 const char* dictionary = (protocol_version() <= SPDY2) ?
2784 kV2Dictionary : kV3Dictionary;
2785 const int dictionary_size = (protocol_version() <= SPDY2) ?
2786 kV2DictionarySize : kV3DictionarySize;
2787 success = deflateSetDictionary(header_compressor_.get(),
2788 reinterpret_cast<const Bytef*>(dictionary),
2789 dictionary_size);
2791 if (success != Z_OK) {
2792 LOG(WARNING) << "deflateSetDictionary failure: " << success;
2793 header_compressor_.reset(NULL);
2794 return NULL;
2796 return header_compressor_.get();
2799 z_stream* SpdyFramer::GetHeaderDecompressor() {
2800 if (header_decompressor_.get())
2801 return header_decompressor_.get(); // Already initialized.
2803 header_decompressor_.reset(new z_stream);
2804 memset(header_decompressor_.get(), 0, sizeof(z_stream));
2806 int success = inflateInit(header_decompressor_.get());
2807 if (success != Z_OK) {
2808 LOG(WARNING) << "inflateInit failure: " << success;
2809 header_decompressor_.reset(NULL);
2810 return NULL;
2812 return header_decompressor_.get();
2815 // Incrementally decompress the control frame's header block, feeding the
2816 // result to the visitor in chunks. Continue this until the visitor
2817 // indicates that it cannot process any more data, or (more commonly) we
2818 // run out of data to deliver.
2819 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
2820 SpdyStreamId stream_id,
2821 const char* data,
2822 size_t len) {
2823 // Get a decompressor or set error.
2824 z_stream* decomp = GetHeaderDecompressor();
2825 if (decomp == NULL) {
2826 LOG(DFATAL) << "Couldn't get decompressor for handling compressed headers.";
2827 set_error(SPDY_DECOMPRESS_FAILURE);
2828 return false;
2831 bool processed_successfully = true;
2832 char buffer[kHeaderDataChunkMaxSize];
2834 decomp->next_in = reinterpret_cast<Bytef*>(const_cast<char*>(data));
2835 decomp->avail_in = len;
2836 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we
2837 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've
2838 // reached this method successfully, stream_id should be nonzero.
2839 DCHECK_LT(0u, stream_id);
2840 while (decomp->avail_in > 0 && processed_successfully) {
2841 decomp->next_out = reinterpret_cast<Bytef*>(buffer);
2842 decomp->avail_out = arraysize(buffer);
2844 int rv = inflate(decomp, Z_SYNC_FLUSH);
2845 if (rv == Z_NEED_DICT) {
2846 const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary
2847 : kV3Dictionary;
2848 const int dictionary_size = (protocol_version() <= SPDY2) ?
2849 kV2DictionarySize : kV3DictionarySize;
2850 const DictionaryIds& ids = g_dictionary_ids.Get();
2851 const uLong dictionary_id = (protocol_version() <= SPDY2) ?
2852 ids.v2_dictionary_id : ids.v3_dictionary_id;
2853 // Need to try again with the right dictionary.
2854 if (decomp->adler == dictionary_id) {
2855 rv = inflateSetDictionary(decomp,
2856 reinterpret_cast<const Bytef*>(dictionary),
2857 dictionary_size);
2858 if (rv == Z_OK)
2859 rv = inflate(decomp, Z_SYNC_FLUSH);
2863 // Inflate will generate a Z_BUF_ERROR if it runs out of input
2864 // without producing any output. The input is consumed and
2865 // buffered internally by zlib so we can detect this condition by
2866 // checking if avail_in is 0 after the call to inflate.
2867 bool input_exhausted = ((rv == Z_BUF_ERROR) && (decomp->avail_in == 0));
2868 if ((rv == Z_OK) || input_exhausted) {
2869 size_t decompressed_len = arraysize(buffer) - decomp->avail_out;
2870 if (decompressed_len > 0) {
2871 processed_successfully = visitor_->OnControlFrameHeaderData(
2872 stream_id, buffer, decompressed_len);
2874 if (!processed_successfully) {
2875 // Assume that the problem was the header block was too large for the
2876 // visitor.
2877 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
2879 } else {
2880 DLOG(WARNING) << "inflate failure: " << rv << " " << len;
2881 set_error(SPDY_DECOMPRESS_FAILURE);
2882 processed_successfully = false;
2885 return processed_successfully;
2888 bool SpdyFramer::IncrementallyDeliverControlFrameHeaderData(
2889 SpdyStreamId stream_id, const char* data, size_t len) {
2890 bool read_successfully = true;
2891 while (read_successfully && len > 0) {
2892 size_t bytes_to_deliver = std::min(len, kHeaderDataChunkMaxSize);
2893 read_successfully = visitor_->OnControlFrameHeaderData(stream_id, data,
2894 bytes_to_deliver);
2895 data += bytes_to_deliver;
2896 len -= bytes_to_deliver;
2897 if (!read_successfully) {
2898 // Assume that the problem was the header block was too large for the
2899 // visitor.
2900 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
2903 return read_successfully;
2906 void SpdyFramer::SerializeNameValueBlockWithoutCompression(
2907 SpdyFrameBuilder* builder,
2908 const SpdyNameValueBlock& name_value_block) const {
2909 // Serialize number of headers.
2910 if (protocol_version() <= SPDY2) {
2911 builder->WriteUInt16(name_value_block.size());
2912 } else {
2913 builder->WriteUInt32(name_value_block.size());
2916 // Serialize each header.
2917 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin();
2918 it != name_value_block.end();
2919 ++it) {
2920 if (protocol_version() <= SPDY2) {
2921 builder->WriteString(it->first);
2922 builder->WriteString(it->second);
2923 } else {
2924 builder->WriteStringPiece32(it->first);
2925 builder->WriteStringPiece32(it->second);
2930 void SpdyFramer::SerializeNameValueBlock(
2931 SpdyFrameBuilder* builder,
2932 const SpdyFrameWithNameValueBlockIR& frame) {
2933 CHECK_GE(SPDY3, protocol_version());
2934 if (!enable_compression_) {
2935 return SerializeNameValueBlockWithoutCompression(builder,
2936 frame.name_value_block());
2939 // First build an uncompressed version to be fed into the compressor.
2940 const size_t uncompressed_len = GetSerializedLength(
2941 protocol_version(), &(frame.name_value_block()));
2942 SpdyFrameBuilder uncompressed_builder(uncompressed_len, protocol_version());
2943 SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
2944 frame.name_value_block());
2945 scoped_ptr<SpdyFrame> uncompressed_payload(uncompressed_builder.take());
2947 z_stream* compressor = GetHeaderCompressor();
2948 if (!compressor) {
2949 LOG(DFATAL) << "Could not obtain compressor.";
2950 return;
2953 base::StatsCounter compressed_frames("spdy.CompressedFrames");
2954 base::StatsCounter pre_compress_bytes("spdy.PreCompressSize");
2955 base::StatsCounter post_compress_bytes("spdy.PostCompressSize");
2957 // Create an output frame.
2958 // Since we'll be performing lots of flushes when compressing the data,
2959 // zlib's lower bounds may be insufficient.
2961 // TODO(akalin): Avoid the duplicate calculation with
2962 // GetSerializedLength(const SpdyHeaderBlock&).
2963 const int compressed_max_size =
2964 2 * deflateBound(compressor, uncompressed_len);
2966 // TODO(phajdan.jr): Clean up after we no longer need
2967 // to workaround http://crbug.com/139744.
2968 #if defined(USE_SYSTEM_ZLIB)
2969 compressor->next_in = reinterpret_cast<Bytef*>(uncompressed_payload->data());
2970 compressor->avail_in = uncompressed_len;
2971 #endif // defined(USE_SYSTEM_ZLIB)
2972 compressor->next_out = reinterpret_cast<Bytef*>(
2973 builder->GetWritableBuffer(compressed_max_size));
2974 compressor->avail_out = compressed_max_size;
2976 // TODO(phajdan.jr): Clean up after we no longer need
2977 // to workaround http://crbug.com/139744.
2978 #if defined(USE_SYSTEM_ZLIB)
2979 int rv = deflate(compressor, Z_SYNC_FLUSH);
2980 if (rv != Z_OK) { // How can we know that it compressed everything?
2981 // This shouldn't happen, right?
2982 LOG(WARNING) << "deflate failure: " << rv;
2983 // TODO(akalin): Upstream this return.
2984 return;
2986 #else
2987 WriteHeaderBlockToZ(&frame.name_value_block(), compressor);
2988 #endif // defined(USE_SYSTEM_ZLIB)
2990 int compressed_size = compressed_max_size - compressor->avail_out;
2991 builder->Seek(compressed_size);
2992 builder->RewriteLength(*this);
2994 pre_compress_bytes.Add(uncompressed_len);
2995 post_compress_bytes.Add(compressed_size);
2997 compressed_frames.Increment();
3000 } // namespace net