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"
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
),
33 struct 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;
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) \
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_; \
70 #define CHANGE_STATE(newstate) \
72 DCHECK(state_ != SPDY_ERROR); \
73 DCHECK_EQ(previous_state_, state_); \
74 previous_state_ = state_; \
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
)
94 uint32 wire
= htonl(id_
& 0x00ffffff) | htonl(flags_
<< 24);
95 if (version
< SPDY3
) {
96 ConvertFlagsAndIdForSpdy2(&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
,
117 bool SpdyFramerVisitorInterface::OnRstStreamFrameData(
118 const char* rst_stream_data
,
123 SpdyFramer::SpdyFramer(SpdyMajorVersion version
)
124 : current_frame_buffer_(new char[kControlFrameBufferSize
]),
125 enable_compression_(true),
126 hpack_encoder_(ObtainHpackHuffmanTable()),
127 hpack_decoder_(ObtainHpackHuffmanTable()),
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
);
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() {
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
178 if (protocol_version() <= SPDY3
) {
180 // control frame header + 2 * 4 (stream IDs) + 1 (priority)
181 // + 1 (unused, was credential slot)
182 return GetControlFrameHeaderSize() + 10;
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
193 size_t size
= GetControlFrameHeaderSize();
194 if (protocol_version() <= SPDY3
) {
196 // control frame header + 4 (stream IDs)
200 // In SPDY 2, there were 2 unused bytes before payload.
201 if (protocol_version() < SPDY3
) {
208 size_t SpdyFramer::GetRstStreamMinimumSize() const {
209 // Size, in bytes, of a RST_STREAM frame.
210 if (protocol_version() <= SPDY3
) {
212 // control frame header + 4 (stream id) + 4 (status code)
213 return GetControlFrameHeaderSize() + 8;
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;
228 return GetControlFrameHeaderSize();
232 size_t SpdyFramer::GetPingSize() const {
233 // Size, in bytes, of this PING frame.
234 if (protocol_version() <= SPDY3
) {
236 // control frame header + 4 (id)
237 return GetControlFrameHeaderSize() + 4;
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)
253 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
254 if (protocol_version() >= SPDY3
) {
261 size_t SpdyFramer::GetHeadersMinimumSize() const {
262 // Size, in bytes, of a HEADERS frame not including the variable-length
264 size_t size
= GetControlFrameHeaderSize();
265 if (protocol_version() <= SPDY3
) {
267 // control frame header + 4 (stream IDs)
271 // In SPDY 2, there were 2 unused bytes before payload.
272 if (protocol_version() <= SPDY2
) {
279 size_t SpdyFramer::GetWindowUpdateSize() const {
280 // Size, in bytes, of a WINDOW_UPDATE frame.
281 if (protocol_version() <= SPDY3
) {
283 // control frame header + 4 (stream id) + 4 (delta)
284 return GetControlFrameHeaderSize() + 8;
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
) {
332 case SPDY_AUTO_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
) {
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
) {
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
:
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
:
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
) {
456 return "WINDOW_UPDATE";
462 return "PUSH_PROMISE";
464 return "CONTINUATION";
466 return "UNKNOWN_CONTROL_TYPE";
469 size_t SpdyFramer::ProcessInput(const char* data
, size_t len
) {
473 size_t original_len
= len
;
475 previous_state_
= state_
;
480 case SPDY_AUTO_RESET
:
484 CHANGE_STATE(SPDY_READING_COMMON_HEADER
);
488 case SPDY_READING_COMMON_HEADER
: {
489 size_t bytes_read
= ProcessCommonHeader(data
, len
);
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
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
);
515 case SPDY_SETTINGS_FRAME_PAYLOAD
: {
516 int bytes_read
= ProcessSettingsFramePayload(data
, len
);
522 case SPDY_CONTROL_FRAME_HEADER_BLOCK
: {
523 int bytes_read
= ProcessControlFrameHeaderBlock(
524 data
, len
, protocol_version() > SPDY3
);
530 case SPDY_RST_STREAM_FRAME_PAYLOAD
: {
531 size_t bytes_read
= ProcessRstStreamFramePayload(data
, len
);
537 case SPDY_GOAWAY_FRAME_PAYLOAD
: {
538 size_t bytes_read
= ProcessGoAwayFramePayload(data
, len
);
544 case SPDY_CONTROL_FRAME_PAYLOAD
: {
545 size_t bytes_read
= ProcessControlFramePayload(data
, len
);
551 case SPDY_READ_PADDING_LENGTH
: {
552 size_t bytes_read
= ProcessFramePaddingLength(data
, len
);
558 case SPDY_CONSUME_PADDING
: {
559 size_t bytes_read
= ProcessFramePadding(data
, len
);
565 case SPDY_IGNORE_REMAINING_PAYLOAD
: {
566 size_t bytes_read
= ProcessIgnoredControlFramePayload(/*data,*/ len
);
572 case SPDY_FORWARD_STREAM_FRAME
: {
573 size_t bytes_read
= ProcessDataFramePayload(data
, len
);
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.
587 } while (state_
!= previous_state_
);
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
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_
));
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 "
646 << " (expected " << protocol_version() << ")";
647 set_error(SPDY_UNSUPPORTED_VERSION
);
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
);
658 successful_read
= reader
->ReadUInt31(¤t_frame_stream_id_
);
660 DCHECK(successful_read
);
662 successful_read
= reader
->ReadUInt8(¤t_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();
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();
687 current_frame_length_
= length_field
+ GetDataFrameMinimumSize();
690 successful_read
= reader
->ReadUInt8(¤t_frame_flags_
);
691 DCHECK(successful_read
);
693 successful_read
= reader
->ReadUInt31(¤t_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
;
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_
728 probable_http_response_
= true;
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
;
748 valid_data_flags
= DATA_FLAG_FIN
;
751 if (current_frame_flags_
& ~valid_data_flags
) {
752 set_error(SPDY_INVALID_DATA_FRAME_FLAGS
);
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
);
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
);
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
);
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
);
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
);
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_
) {
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
);
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
);
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
);
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
);
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
);
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
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
);
891 size_t min_size
= GetHeadersMinimumSize();
892 if (protocol_version() > SPDY3
&&
893 (current_frame_flags_
& HEADERS_FLAG_PRIORITY
)) {
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
);
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
);
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
);
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
);
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
);
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.
949 set_error(SPDY_INVALID_CONTROL_FRAME
);
953 if (state_
== SPDY_ERROR
) {
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
);
964 if (current_frame_type_
== GOAWAY
) {
965 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD
);
969 if (current_frame_type_
== RST_STREAM
) {
970 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD
);
974 // Determine the frame size without variable-length data.
975 int32 frame_size_without_variable_data
;
976 switch (current_frame_type_
) {
978 syn_frame_processed_
= true;
979 frame_size_without_variable_data
= GetSynStreamMinimumSize();
982 syn_frame_processed_
= true;
983 frame_size_without_variable_data
= GetSynReplyMinimumSize();
986 frame_size_without_variable_data
= GetSettingsMinimumSize();
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
996 frame_size_without_variable_data
= GetPushPromiseMinimumSize();
999 frame_size_without_variable_data
= GetContinuationMinimumSize();
1002 frame_size_without_variable_data
= -1;
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
);
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
);
1031 CHANGE_STATE(SPDY_CONTROL_FRAME_PAYLOAD
);
1034 size_t SpdyFramer::UpdateCurrentFrameBuffer(const char** data
, size_t* len
,
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_
,
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();
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.
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
);
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.
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
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
,
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
) {
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();
1132 if (clas
== kZStandardData
) {
1133 rv
= deflate(out
, Z_NO_FLUSH
);
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
,
1151 DCHECK_LE(length
, sizeof(buf
));
1152 for (unsigned i
= 1; i
<= length
; i
++) {
1153 buf
[length
- i
] = n
;
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
1162 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock
* headers
,
1163 z_stream
* z
) const {
1164 unsigned length_length
= 4;
1165 if (spdy_version_
< 3)
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
1181 std::vector
<base::StringPiece
> cookie_values
;
1182 size_t cookie_length
= 0;
1183 base::StringPiece
cookie_data(it
->second
);
1186 while (!cookie_data
.empty() &&
1187 (cookie_data
[0] == ' ' || cookie_data
[0] == '\t')) {
1188 cookie_data
.remove_prefix(1);
1190 if (cookie_data
.empty())
1194 for (i
= 0; i
< cookie_data
.size(); i
++) {
1195 if (cookie_data
[i
] == ';')
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);
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
++) {
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() + ";";
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
);
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
);
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
,
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_
) {
1277 DCHECK_GE(SPDY3
, protocol_version());
1278 bool successful_read
= true;
1279 successful_read
= reader
.ReadUInt31(¤t_frame_stream_id_
);
1280 DCHECK(successful_read
);
1281 if (current_frame_stream_id_
== 0) {
1282 set_error(SPDY_INVALID_CONTROL_FRAME
);
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;
1296 priority
= priority
>> 5;
1299 // Seek past unused byte; used to be credential slot in SPDY 3.
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
,
1313 (current_frame_flags_
& CONTROL_FLAG_FIN
) != 0,
1314 (current_frame_flags_
& CONTROL_FLAG_UNIDIRECTIONAL
) != 0);
1316 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK
);
1319 if (protocol_version() > SPDY3
&&
1320 current_frame_flags_
& SETTINGS_FLAG_ACK
) {
1321 visitor_
->OnSettingsAck();
1322 CHANGE_STATE(SPDY_AUTO_RESET
);
1324 visitor_
->OnSettings(current_frame_flags_
&
1325 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
);
1326 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD
);
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(¤t_frame_stream_id_
);
1339 DCHECK(successful_read
);
1341 if (current_frame_stream_id_
== 0) {
1342 set_error(SPDY_INVALID_CONTROL_FRAME
);
1345 if (protocol_version() <= SPDY2
) {
1346 // SPDY 2 had two unused bytes here. Seek past them.
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_
,
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
1386 current_frame_flags_
& CONTROL_FLAG_FIN
,
1387 false); // unidirectional
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
);
1399 DCHECK_LT(SPDY3
, protocol_version());
1400 if (current_frame_stream_id_
== 0) {
1401 set_error(SPDY_INVALID_CONTROL_FRAME
);
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
);
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_
,
1423 (current_frame_flags_
&
1424 PUSH_PROMISE_FLAG_END_PUSH_PROMISE
) != 0);
1426 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK
);
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
);
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
);
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
,
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_
,
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
);
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;
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
;
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
);
1530 if (!processed_successfully
) {
1534 // Return amount processed.
1535 return process_bytes
;
1538 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data
,
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(
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
;
1562 // Continue updating settings_scratch_.setting_buf.
1563 memcpy(settings_scratch_
.setting_buf
+ settings_scratch_
.setting_buf_len
,
1564 data
+ processed_bytes
,
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;
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);
1604 SpdyFrameBuilder
builder(
1605 GetSerializedLength(protocol_version(), &block
),
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
) {
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)));
1631 id_field
= *(reinterpret_cast<const uint8
*>(data
));
1632 value
= ntohl(*(reinterpret_cast<const uint32
*>(data
+ 1)));
1636 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field
)) {
1637 DLOG(WARNING
) << "Unknown SETTINGS ID: " << id_field
;
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
<< ").";
1651 settings_scratch_
.last_setting_id
= id
;
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
<< ": "
1662 // Validation succeeded. Pass on to visitor.
1663 visitor_
->OnSetting(id
, flags
, value
);
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_
) {
1681 bool is_ack
= protocol_version() > SPDY3
&&
1682 (current_frame_flags_
& PING_FLAG_ACK
);
1683 bool successful_read
= true;
1684 if (protocol_version() <= SPDY3
) {
1686 successful_read
= reader
.ReadUInt32(&id32
);
1689 successful_read
= reader
.ReadUInt64(&id
);
1691 DCHECK(successful_read
);
1692 DCHECK(reader
.IsDoneReading());
1693 visitor_
->OnPing(id
, is_ack
);
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(¤t_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_
,
1711 DCHECK_LT(SPDY3
, protocol_version());
1712 DCHECK(reader
.IsDoneReading());
1713 visitor_
->OnBlocked(current_frame_stream_id_
);
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
) {
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(¤t_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(),
1761 status
= SpdyConstants::ParseGoAwayStatus(protocol_version(),
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
);
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;
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
) {
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(¤t_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(),
1831 status
= static_cast<SpdyRstStreamStatus
>(status_raw
);
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
);
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;
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
) {
1872 ++remaining_padding_length_fields_
;
1874 if (current_frame_flags_
& DATA_FLAG_PAD_HIGH
) {
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
);
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
);
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
);
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
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,*/
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.
1983 if (protocol_version() <= SPDY2
) {
1985 if (!reader
.ReadUInt16(&temp
)) {
1986 DVLOG(1) << "Unable to read number of headers.";
1991 if (!reader
.ReadUInt32(&num_headers
)) {
1992 DVLOG(1) << "Unable to read number of headers.";
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
<< ").";
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
<< ").";
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
<< ").";
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();
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());
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
) {
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
);
2150 hpack_encoder_
.EncodeHeaderSetWithoutCompression(
2151 syn_stream
.name_value_block(), &hpack_encoding
);
2153 size
+= hpack_encoding
.size();
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.
2166 builder
.BeginNewFrame(*this,
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());
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(),
2191 return builder
.take();
2194 SpdySerializedFrame
* SpdyFramer::SerializeSynReply(
2195 const SpdySynReplyIR
& syn_reply
) {
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
);
2215 hpack_encoder_
.EncodeHeaderSetWithoutCompression(
2216 syn_reply
.name_value_block(), &hpack_encoding
);
2218 size
+= hpack_encoding
.size();
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());
2228 builder
.BeginNewFrame(*this,
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());
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(),
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());
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 {
2294 if (protocol_version() <= SPDY3
) {
2295 if (settings
.clear_settings()) {
2296 flags
|= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS
;
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
);
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();
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(
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);
2342 builder
.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(),
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()));
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
);
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
) {
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();
2433 string hpack_encoding
;
2434 if (protocol_version() > SPDY3
) {
2435 if (enable_compression_
) {
2436 hpack_encoder_
.EncodeHeaderSet(
2437 headers
.name_value_block(), &hpack_encoding
);
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
;
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());
2457 builder
.BeginNewFrame(*this,
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
,
2473 headers
.stream_id(),
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(),
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());
2500 builder
.BeginNewFrame(*this,
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());
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
);
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
;
2546 size
+= GetSerializedLength(push_promise
.name_value_block());
2549 SpdyFrameBuilder
builder(size
, protocol_version());
2550 builder
.BeginNewFrame(*this,
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
,
2560 push_promise
.stream_id(),
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());
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
);
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();
2619 class FrameSerializationVisitor
: public SpdyFrameVisitor
{
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
));
2667 SpdyFramer
* framer_
;
2668 scoped_ptr
<SpdySerializedFrame
> frame_
;
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;
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
;
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
) {
2743 builder
->BeginNewFrame(*this,
2747 // Write payload fragment.
2748 builder
->WriteBytes(&hpack_encoding
[hpack_encoding
.size() -
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(),
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
),
2791 if (success
!= Z_OK
) {
2792 LOG(WARNING
) << "deflateSetDictionary failure: " << success
;
2793 header_compressor_
.reset(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
);
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
,
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
);
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
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
),
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
2877 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE
);
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
,
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
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());
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();
2920 if (protocol_version() <= SPDY2
) {
2921 builder
->WriteString(it
->first
);
2922 builder
->WriteString(it
->second
);
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();
2949 LOG(DFATAL
) << "Could not obtain compressor.";
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.
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();