OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/spdy/spdy_framer.h" | 5 #include "net/spdy/spdy_framer.h" |
6 | 6 |
7 #include <string.h> | 7 #include <string.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 #include <cctype> | 10 #include <cctype> |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
192 expect_continuation_(0), | 192 expect_continuation_(0), |
193 visitor_(NULL), | 193 visitor_(NULL), |
194 debug_visitor_(NULL), | 194 debug_visitor_(NULL), |
195 header_handler_(nullptr), | 195 header_handler_(nullptr), |
196 display_protocol_("SPDY"), | 196 display_protocol_("SPDY"), |
197 protocol_version_(version), | 197 protocol_version_(version), |
198 enable_compression_(true), | 198 enable_compression_(true), |
199 syn_frame_processed_(false), | 199 syn_frame_processed_(false), |
200 probable_http_response_(false), | 200 probable_http_response_(false), |
201 end_stream_when_done_(false) { | 201 end_stream_when_done_(false) { |
202 DCHECK(protocol_version_ == SPDY3 || protocol_version_ == HTTP2); | 202 DCHECK(protocol_version_ == HTTP2); |
203 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it | 203 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it |
204 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. | 204 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. |
205 // Therefore this assertion is unnecessarily strict. | 205 // Therefore this assertion is unnecessarily strict. |
206 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, | 206 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, |
207 "Our send limit should be at most our receive limit"); | 207 "Our send limit should be at most our receive limit"); |
208 Reset(); | 208 Reset(); |
209 | 209 |
210 if (version == HTTP2 && adapter_factory != nullptr) { | 210 if (version == HTTP2 && adapter_factory != nullptr) { |
211 decoder_adapter_ = adapter_factory(this); | 211 decoder_adapter_ = adapter_factory(this); |
212 } | 212 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
291 } | 291 } |
292 | 292 |
293 // Size, in bytes, of the control frame header. | 293 // Size, in bytes, of the control frame header. |
294 size_t SpdyFramer::GetFrameHeaderSize() const { | 294 size_t SpdyFramer::GetFrameHeaderSize() const { |
295 return SpdyConstants::GetFrameHeaderSize(protocol_version_); | 295 return SpdyConstants::GetFrameHeaderSize(protocol_version_); |
296 } | 296 } |
297 | 297 |
298 size_t SpdyFramer::GetSynStreamMinimumSize() const { | 298 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
299 // Size, in bytes, of a SYN_STREAM frame not including the variable-length | 299 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
300 // header block. | 300 // header block. |
301 if (protocol_version_ == SPDY3) { | 301 return GetFrameHeaderSize() + kPriorityDependencyPayloadSize + |
302 // Calculated as: | 302 kPriorityWeightPayloadSize; |
303 // control frame header + 2 * 4 (stream IDs) + 1 (priority) | |
304 // + 1 (unused) | |
305 return GetFrameHeaderSize() + 10; | |
306 } else { | |
307 return GetFrameHeaderSize() + kPriorityDependencyPayloadSize + | |
308 kPriorityWeightPayloadSize; | |
309 } | |
310 } | 303 } |
311 | 304 |
312 size_t SpdyFramer::GetSynReplyMinimumSize() const { | 305 size_t SpdyFramer::GetSynReplyMinimumSize() const { |
313 // Size, in bytes, of a SYN_REPLY frame not including the variable-length | 306 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
314 // header block. | 307 // header block. |
315 size_t size = GetFrameHeaderSize(); | 308 return GetFrameHeaderSize(); |
316 if (protocol_version_ == SPDY3) { | |
317 // Calculated as: | |
318 // control frame header + 4 (stream IDs) | |
319 size += 4; | |
320 } | |
321 | |
322 return size; | |
323 } | 309 } |
324 | 310 |
325 // TODO(jamessynge): Rename this to GetRstStreamSize as the frame is fixed size. | 311 // TODO(jamessynge): Rename this to GetRstStreamSize as the frame is fixed size. |
326 size_t SpdyFramer::GetRstStreamMinimumSize() const { | 312 size_t SpdyFramer::GetRstStreamMinimumSize() const { |
327 // Size, in bytes, of a RST_STREAM frame. | 313 // Size, in bytes, of a RST_STREAM frame. |
328 if (protocol_version_ == SPDY3) { | 314 // Calculated as: |
329 // Calculated as: | 315 // frame prefix + 4 (status code) |
330 // control frame header + 4 (stream id) + 4 (status code) | 316 return GetFrameHeaderSize() + 4; |
331 return GetFrameHeaderSize() + 8; | |
332 } else { | |
333 // Calculated as: | |
334 // frame prefix + 4 (status code) | |
335 return GetFrameHeaderSize() + 4; | |
336 } | |
337 } | 317 } |
338 | 318 |
339 size_t SpdyFramer::GetSettingsMinimumSize() const { | 319 size_t SpdyFramer::GetSettingsMinimumSize() const { |
340 // Size, in bytes, of a SETTINGS frame not including the IDs and values | 320 // Size, in bytes, of a SETTINGS frame not including the IDs and values |
341 // from the variable-length value block. Calculated as: | 321 // from the variable-length value block. |
342 // control frame header + 4 (number of ID/value pairs) | 322 return GetFrameHeaderSize(); |
343 if (protocol_version_ == SPDY3) { | |
344 return GetFrameHeaderSize() + 4; | |
345 } else { | |
346 return GetFrameHeaderSize(); | |
347 } | |
348 } | 323 } |
349 | 324 |
350 size_t SpdyFramer::GetPingSize() const { | 325 size_t SpdyFramer::GetPingSize() const { |
351 // Size, in bytes, of this PING frame. | 326 // Size, in bytes, of this PING frame. |
352 if (protocol_version_ == SPDY3) { | 327 // Calculated as: |
353 // Calculated as: | 328 // control frame header + 8 (id) |
354 // control frame header + 4 (id) | 329 return GetFrameHeaderSize() + 8; |
355 return GetFrameHeaderSize() + 4; | |
356 } else { | |
357 // Calculated as: | |
358 // control frame header + 8 (id) | |
359 return GetFrameHeaderSize() + 8; | |
360 } | |
361 } | 330 } |
362 | 331 |
363 size_t SpdyFramer::GetGoAwayMinimumSize() const { | 332 size_t SpdyFramer::GetGoAwayMinimumSize() const { |
364 // Size, in bytes, of this GOAWAY frame. Calculated as: | 333 // Size, in bytes, of this GOAWAY frame. Calculated as: |
365 // Control frame header + last stream id (4 bytes) + error code (4 bytes). | 334 // Control frame header + last stream id (4 bytes) + error code (4 bytes). |
366 return GetFrameHeaderSize() + 8; | 335 return GetFrameHeaderSize() + 8; |
367 } | 336 } |
368 | 337 |
369 size_t SpdyFramer::GetHeadersMinimumSize() const { | 338 size_t SpdyFramer::GetHeadersMinimumSize() const { |
370 // Size, in bytes, of a HEADERS frame not including the variable-length | 339 // Size, in bytes, of a HEADERS frame not including the variable-length |
371 // header block. | 340 // header block. |
372 size_t size = GetFrameHeaderSize(); | 341 return GetFrameHeaderSize(); |
373 if (protocol_version_ == SPDY3) { | |
374 // Calculated as: | |
375 // control frame header + 4 (stream IDs) | |
376 size += 4; | |
377 } | |
378 | |
379 return size; | |
380 } | 342 } |
381 | 343 |
382 size_t SpdyFramer::GetWindowUpdateSize() const { | 344 size_t SpdyFramer::GetWindowUpdateSize() const { |
383 // Size, in bytes, of a WINDOW_UPDATE frame. | 345 // Size, in bytes, of a WINDOW_UPDATE frame. |
384 if (protocol_version_ == SPDY3) { | 346 // Calculated as: |
385 // Calculated as: | 347 // frame prefix + 4 (delta) |
386 // control frame header + 4 (stream id) + 4 (delta) | 348 return GetFrameHeaderSize() + 4; |
387 return GetFrameHeaderSize() + 8; | |
388 } else { | |
389 // Calculated as: | |
390 // frame prefix + 4 (delta) | |
391 return GetFrameHeaderSize() + 4; | |
392 } | |
393 } | 349 } |
394 | 350 |
395 size_t SpdyFramer::GetBlockedSize() const { | 351 size_t SpdyFramer::GetBlockedSize() const { |
396 DCHECK_EQ(HTTP2, protocol_version_); | 352 DCHECK_EQ(HTTP2, protocol_version_); |
397 // Size, in bytes, of a BLOCKED frame. | 353 // Size, in bytes, of a BLOCKED frame. |
398 // The BLOCKED frame has no payload beyond the control frame header. | 354 // The BLOCKED frame has no payload beyond the control frame header. |
399 return GetFrameHeaderSize(); | 355 return GetFrameHeaderSize(); |
400 } | 356 } |
401 | 357 |
402 size_t SpdyFramer::GetPushPromiseMinimumSize() const { | 358 size_t SpdyFramer::GetPushPromiseMinimumSize() const { |
(...skipping 371 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
774 | 730 |
775 void SpdyFramer::SpdySettingsScratch::Reset() { | 731 void SpdyFramer::SpdySettingsScratch::Reset() { |
776 buffer.Rewind(); | 732 buffer.Rewind(); |
777 last_setting_id = -1; | 733 last_setting_id = -1; |
778 } | 734 } |
779 | 735 |
780 SpdyFrameType SpdyFramer::ValidateFrameHeader(bool is_control_frame, | 736 SpdyFrameType SpdyFramer::ValidateFrameHeader(bool is_control_frame, |
781 int frame_type_field, | 737 int frame_type_field, |
782 size_t payload_length_field) { | 738 size_t payload_length_field) { |
783 if (!SpdyConstants::IsValidFrameType(protocol_version_, frame_type_field)) { | 739 if (!SpdyConstants::IsValidFrameType(protocol_version_, frame_type_field)) { |
784 if (protocol_version_ == SPDY3) { | 740 // In HTTP2 we ignore unknown frame types for extensibility, as long as |
785 if (is_control_frame) { | 741 // the rest of the control frame header is valid. |
786 DLOG(WARNING) << "Invalid control frame type " << frame_type_field | 742 // We rely on the visitor to check validity of current_frame_stream_id_. |
787 << " (protocol version: " << protocol_version_ << ")"; | 743 bool valid_stream = |
788 set_error(SPDY_INVALID_CONTROL_FRAME); | 744 visitor_->OnUnknownFrame(current_frame_stream_id_, frame_type_field); |
789 } else { | 745 if (expect_continuation_) { |
790 // Else it's a SPDY3 data frame which we don't validate further here | 746 // Report an unexpected frame error and close the connection |
791 } | 747 // if we expect a continuation and receive an unknown frame. |
| 748 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
| 749 << "frame, but instead received an unknown frame of type " |
| 750 << frame_type_field; |
| 751 set_error(SPDY_UNEXPECTED_FRAME); |
| 752 } else if (!valid_stream) { |
| 753 // Report an invalid frame error and close the stream if the |
| 754 // stream_id is not valid. |
| 755 DLOG(WARNING) << "Unknown control frame type " << frame_type_field |
| 756 << " received on invalid stream " |
| 757 << current_frame_stream_id_; |
| 758 set_error(SPDY_INVALID_CONTROL_FRAME); |
792 } else { | 759 } else { |
793 // In HTTP2 we ignore unknown frame types for extensibility, as long as | 760 DVLOG(1) << "Ignoring unknown frame type."; |
794 // the rest of the control frame header is valid. | 761 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
795 // We rely on the visitor to check validity of current_frame_stream_id_. | |
796 bool valid_stream = | |
797 visitor_->OnUnknownFrame(current_frame_stream_id_, frame_type_field); | |
798 if (expect_continuation_) { | |
799 // Report an unexpected frame error and close the connection | |
800 // if we expect a continuation and receive an unknown frame. | |
801 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | |
802 << "frame, but instead received an unknown frame of type " | |
803 << frame_type_field; | |
804 set_error(SPDY_UNEXPECTED_FRAME); | |
805 } else if (!valid_stream) { | |
806 // Report an invalid frame error and close the stream if the | |
807 // stream_id is not valid. | |
808 DLOG(WARNING) << "Unknown control frame type " << frame_type_field | |
809 << " received on invalid stream " | |
810 << current_frame_stream_id_; | |
811 set_error(SPDY_INVALID_CONTROL_FRAME); | |
812 } else { | |
813 DVLOG(1) << "Ignoring unknown frame type."; | |
814 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | |
815 } | |
816 } | 762 } |
817 return DATA; | 763 return DATA; |
818 } | 764 } |
819 | 765 |
820 SpdyFrameType frame_type = | 766 SpdyFrameType frame_type = |
821 SpdyConstants::ParseFrameType(protocol_version_, frame_type_field); | 767 SpdyConstants::ParseFrameType(protocol_version_, frame_type_field); |
822 | 768 |
823 if (protocol_version_ == HTTP2) { | 769 if (protocol_version_ == HTTP2) { |
824 if (!SpdyConstants::IsValidHTTP2FrameStreamId(current_frame_stream_id_, | 770 if (!SpdyConstants::IsValidHTTP2FrameStreamId(current_frame_stream_id_, |
825 frame_type)) { | 771 frame_type)) { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
872 | 818 |
873 SpdyFrameReader reader(current_frame_buffer_.data(), | 819 SpdyFrameReader reader(current_frame_buffer_.data(), |
874 current_frame_buffer_.len()); | 820 current_frame_buffer_.len()); |
875 bool is_control_frame = false; | 821 bool is_control_frame = false; |
876 | 822 |
877 int control_frame_type_field = | 823 int control_frame_type_field = |
878 SpdyConstants::DataFrameType(protocol_version_); | 824 SpdyConstants::DataFrameType(protocol_version_); |
879 // ProcessControlFrameHeader() will set current_frame_type_ to the | 825 // ProcessControlFrameHeader() will set current_frame_type_ to the |
880 // correct value if this is a valid control frame. | 826 // correct value if this is a valid control frame. |
881 current_frame_type_ = DATA; | 827 current_frame_type_ = DATA; |
882 if (protocol_version_ == SPDY3) { | 828 uint32_t length_field = 0; |
883 uint16_t version = 0; | 829 bool successful_read = reader.ReadUInt24(&length_field); |
884 bool successful_read = reader.ReadUInt16(&version); | 830 DCHECK(successful_read); |
885 DCHECK(successful_read); | |
886 is_control_frame = (version & kControlFlagMask) != 0; | |
887 if (is_control_frame) { | |
888 version &= ~kControlFlagMask; | |
889 if (version != kSpdy3Version) { | |
890 // Version does not match the version the framer was initialized with. | |
891 DVLOG(1) << "Unsupported SPDY version " << version << " (expected " | |
892 << kSpdy3Version << ")"; | |
893 set_error(SPDY_UNSUPPORTED_VERSION); | |
894 return 0; | |
895 } | |
896 uint16_t control_frame_type_field_uint16; | |
897 successful_read = reader.ReadUInt16(&control_frame_type_field_uint16); | |
898 control_frame_type_field = control_frame_type_field_uint16; | |
899 } else { | |
900 reader.Rewind(); | |
901 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
902 } | |
903 DCHECK(successful_read); | |
904 | 831 |
905 successful_read = reader.ReadUInt8(¤t_frame_flags_); | 832 uint8_t control_frame_type_field_uint8; |
906 DCHECK(successful_read); | 833 successful_read = reader.ReadUInt8(&control_frame_type_field_uint8); |
| 834 DCHECK(successful_read); |
| 835 // We check control_frame_type_field's validity in |
| 836 // ProcessControlFrameHeader(). |
| 837 control_frame_type_field = control_frame_type_field_uint8; |
| 838 is_control_frame = control_frame_type_field != |
| 839 SpdyConstants::SerializeFrameType(protocol_version_, DATA); |
907 | 840 |
908 uint32_t length_field = 0; | 841 current_frame_length_ = length_field + GetFrameHeaderSize(); |
909 successful_read = reader.ReadUInt24(&length_field); | |
910 DCHECK(successful_read); | |
911 remaining_data_length_ = length_field; | |
912 current_frame_length_ = remaining_data_length_ + reader.GetBytesConsumed(); | |
913 } else { | |
914 uint32_t length_field = 0; | |
915 bool successful_read = reader.ReadUInt24(&length_field); | |
916 DCHECK(successful_read); | |
917 | 842 |
918 uint8_t control_frame_type_field_uint8; | 843 successful_read = reader.ReadUInt8(¤t_frame_flags_); |
919 successful_read = reader.ReadUInt8(&control_frame_type_field_uint8); | 844 DCHECK(successful_read); |
920 DCHECK(successful_read); | |
921 // We check control_frame_type_field's validity in | |
922 // ProcessControlFrameHeader(). | |
923 control_frame_type_field = control_frame_type_field_uint8; | |
924 is_control_frame = | |
925 control_frame_type_field != | |
926 SpdyConstants::SerializeFrameType(protocol_version_, DATA); | |
927 | 845 |
928 current_frame_length_ = length_field + GetFrameHeaderSize(); | 846 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); |
| 847 DCHECK(successful_read); |
929 | 848 |
930 successful_read = reader.ReadUInt8(¤t_frame_flags_); | 849 remaining_data_length_ = current_frame_length_ - reader.GetBytesConsumed(); |
931 DCHECK(successful_read); | |
932 | |
933 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
934 DCHECK(successful_read); | |
935 | |
936 remaining_data_length_ = current_frame_length_ - reader.GetBytesConsumed(); | |
937 } | |
938 | 850 |
939 DCHECK_EQ(GetFrameHeaderSize(), reader.GetBytesConsumed()); | 851 DCHECK_EQ(GetFrameHeaderSize(), reader.GetBytesConsumed()); |
940 DCHECK_EQ(current_frame_length_, | 852 DCHECK_EQ(current_frame_length_, |
941 remaining_data_length_ + reader.GetBytesConsumed()); | 853 remaining_data_length_ + reader.GetBytesConsumed()); |
942 | 854 |
943 // This is just a sanity check for help debugging early frame errors. | 855 // This is just a sanity check for help debugging early frame errors. |
944 if (remaining_data_length_ > 1000000u) { | 856 if (remaining_data_length_ > 1000000u) { |
945 // The strncmp for 5 is safe because we only hit this point if we | 857 // The strncmp for 5 is safe because we only hit this point if we |
946 // have kMinCommonHeader (8) bytes | 858 // have kMinCommonHeader (8) bytes |
947 if (!syn_frame_processed_ && | 859 if (!syn_frame_processed_ && |
(...skipping 12 matching lines...) Expand all Loading... |
960 control_frame_type_field, current_frame_flags_); | 872 control_frame_type_field, current_frame_flags_); |
961 | 873 |
962 current_frame_type_ = ValidateFrameHeader( | 874 current_frame_type_ = ValidateFrameHeader( |
963 is_control_frame, control_frame_type_field, remaining_data_length_); | 875 is_control_frame, control_frame_type_field, remaining_data_length_); |
964 | 876 |
965 if (state_ == SPDY_ERROR || state_ == SPDY_IGNORE_REMAINING_PAYLOAD) { | 877 if (state_ == SPDY_ERROR || state_ == SPDY_IGNORE_REMAINING_PAYLOAD) { |
966 return original_len - len; | 878 return original_len - len; |
967 } | 879 } |
968 | 880 |
969 if (!is_control_frame) { | 881 if (!is_control_frame) { |
970 uint8_t valid_data_flags = 0; | 882 uint8_t valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED; |
971 if (protocol_version_ == SPDY3) { | |
972 valid_data_flags = DATA_FLAG_FIN; | |
973 } else { | |
974 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_PADDED; | |
975 } | |
976 | 883 |
977 if (current_frame_flags_ & ~valid_data_flags) { | 884 if (current_frame_flags_ & ~valid_data_flags) { |
978 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 885 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
979 } else { | 886 } else { |
980 visitor_->OnDataFrameHeader(current_frame_stream_id_, | 887 visitor_->OnDataFrameHeader(current_frame_stream_id_, |
981 remaining_data_length_, | 888 remaining_data_length_, |
982 current_frame_flags_ & DATA_FLAG_FIN); | 889 current_frame_flags_ & DATA_FLAG_FIN); |
983 if (remaining_data_length_ > 0) { | 890 if (remaining_data_length_ > 0) { |
984 CHANGE_STATE(SPDY_READ_DATA_FRAME_PADDING_LENGTH); | 891 CHANGE_STATE(SPDY_READ_DATA_FRAME_PADDING_LENGTH); |
985 } else { | 892 } else { |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1023 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 930 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1024 } else if (current_frame_flags_ != 0) { | 931 } else if (current_frame_flags_ != 0) { |
1025 VLOG(1) << "Undefined frame flags for RST_STREAM frame: " << hex | 932 VLOG(1) << "Undefined frame flags for RST_STREAM frame: " << hex |
1026 << static_cast<int>(current_frame_flags_); | 933 << static_cast<int>(current_frame_flags_); |
1027 current_frame_flags_ = 0; | 934 current_frame_flags_ = 0; |
1028 } | 935 } |
1029 break; | 936 break; |
1030 case SETTINGS: | 937 case SETTINGS: |
1031 { | 938 { |
1032 // Make sure that we have an integral number of 8-byte key/value pairs, | 939 // Make sure that we have an integral number of 8-byte key/value pairs, |
1033 // plus a 4-byte length field in SPDY3 and below. | |
1034 size_t values_prefix_size = (protocol_version_ == SPDY3 ? 4 : 0); | |
1035 // Size of each key/value pair in bytes. | 940 // Size of each key/value pair in bytes. |
1036 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version_); | 941 int setting_size = 6; |
1037 if (current_frame_length_ < GetSettingsMinimumSize() || | 942 if (current_frame_length_ < GetSettingsMinimumSize() || |
1038 (current_frame_length_ - GetFrameHeaderSize()) % setting_size != | 943 (current_frame_length_ - GetFrameHeaderSize()) % setting_size != 0) { |
1039 values_prefix_size) { | |
1040 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 944 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
1041 << current_frame_length_; | 945 << current_frame_length_; |
1042 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 946 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1043 } else if (protocol_version_ == SPDY3 && | |
1044 current_frame_flags_ & | |
1045 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { | |
1046 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | |
1047 } else if (protocol_version_ == HTTP2 && | 947 } else if (protocol_version_ == HTTP2 && |
1048 current_frame_flags_ & SETTINGS_FLAG_ACK && | 948 current_frame_flags_ & SETTINGS_FLAG_ACK && |
1049 current_frame_length_ > GetSettingsMinimumSize()) { | 949 current_frame_length_ > GetSettingsMinimumSize()) { |
1050 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 950 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1051 } else if (protocol_version_ == HTTP2 && | 951 } else if (protocol_version_ == HTTP2 && |
1052 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { | 952 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { |
1053 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex | 953 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex |
1054 << static_cast<int>(current_frame_flags_); | 954 << static_cast<int>(current_frame_flags_); |
1055 current_frame_flags_ &= SETTINGS_FLAG_ACK; | 955 current_frame_flags_ &= SETTINGS_FLAG_ACK; |
1056 } | 956 } |
1057 break; | 957 break; |
1058 } | 958 } |
1059 case PING: | 959 case PING: |
1060 if (current_frame_length_ != GetPingSize()) { | 960 if (current_frame_length_ != GetPingSize()) { |
1061 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 961 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1062 } else { | 962 } else { |
1063 if (protocol_version_ == SPDY3 && current_frame_flags_ != 0) { | 963 if (protocol_version_ == HTTP2 && |
1064 VLOG(1) << "Undefined frame flags for PING frame: " << hex | 964 current_frame_flags_ & ~PING_FLAG_ACK) { |
1065 << static_cast<int>(current_frame_flags_); | |
1066 current_frame_flags_ = 0; | |
1067 } else if (protocol_version_ == HTTP2 && | |
1068 current_frame_flags_ & ~PING_FLAG_ACK) { | |
1069 VLOG(1) << "Undefined frame flags for PING frame: " << hex | 965 VLOG(1) << "Undefined frame flags for PING frame: " << hex |
1070 << static_cast<int>(current_frame_flags_); | 966 << static_cast<int>(current_frame_flags_); |
1071 current_frame_flags_ &= PING_FLAG_ACK; | 967 current_frame_flags_ &= PING_FLAG_ACK; |
1072 } | 968 } |
1073 } | 969 } |
1074 break; | 970 break; |
1075 case GOAWAY: | 971 case GOAWAY: |
1076 { | 972 { |
1077 // For SPDY/3, there are only mandatory fields and the header has a | 973 // For HTTP/2, optional opaque data may be appended to the |
1078 // fixed length. For HTTP/2, optional opaque data may be appended to the | 974 // GOAWAY frame, thus there is only a minimal length restriction. |
1079 // GOAWAY frame, thus there is only a minimal length restriction. | 975 if (protocol_version_ == HTTP2 && |
1080 if ((protocol_version_ == SPDY3 && | 976 current_frame_length_ < GetGoAwayMinimumSize()) { |
1081 current_frame_length_ != GetGoAwayMinimumSize()) || | 977 set_error(SPDY_INVALID_CONTROL_FRAME); |
1082 (protocol_version_ == HTTP2 && | |
1083 current_frame_length_ < GetGoAwayMinimumSize())) { | |
1084 set_error(SPDY_INVALID_CONTROL_FRAME); | |
1085 } else if (current_frame_flags_ != 0) { | 978 } else if (current_frame_flags_ != 0) { |
1086 VLOG(1) << "Undefined frame flags for GOAWAY frame: " << hex | 979 VLOG(1) << "Undefined frame flags for GOAWAY frame: " << hex |
1087 << static_cast<int>(current_frame_flags_); | 980 << static_cast<int>(current_frame_flags_); |
1088 current_frame_flags_ = 0; | 981 current_frame_flags_ = 0; |
1089 } | 982 } |
1090 break; | 983 break; |
1091 } | 984 } |
1092 case HEADERS: | 985 case HEADERS: |
1093 { | 986 { |
1094 size_t min_size = GetHeadersMinimumSize(); | 987 size_t min_size = GetHeadersMinimumSize(); |
1095 if (protocol_version_ == HTTP2 && | 988 if (protocol_version_ == HTTP2 && |
1096 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { | 989 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { |
1097 min_size += 4; | 990 min_size += 4; |
1098 } | 991 } |
1099 if (current_frame_length_ < min_size) { | 992 if (current_frame_length_ < min_size) { |
1100 // TODO(mlavan): check here for HEADERS with no payload? | 993 // TODO(mlavan): check here for HEADERS with no payload? |
1101 // (not allowed in HTTP2) | 994 // (not allowed in HTTP2) |
1102 set_error(SPDY_INVALID_CONTROL_FRAME); | 995 set_error(SPDY_INVALID_CONTROL_FRAME); |
1103 } else if (protocol_version_ == SPDY3 && | |
1104 current_frame_flags_ & ~CONTROL_FLAG_FIN) { | |
1105 VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex | |
1106 << static_cast<int>(current_frame_flags_); | |
1107 current_frame_flags_ &= CONTROL_FLAG_FIN; | |
1108 } else if (protocol_version_ == HTTP2 && | 996 } else if (protocol_version_ == HTTP2 && |
1109 current_frame_flags_ & | 997 current_frame_flags_ & |
1110 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 998 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
1111 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED)) { | 999 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED)) { |
1112 VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex | 1000 VLOG(1) << "Undefined frame flags for HEADERS frame: " << hex |
1113 << static_cast<int>(current_frame_flags_); | 1001 << static_cast<int>(current_frame_flags_); |
1114 current_frame_flags_ &= | 1002 current_frame_flags_ &= |
1115 (CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 1003 (CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
1116 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED); | 1004 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PADDED); |
1117 } | 1005 } |
1118 } | 1006 } |
1119 break; | 1007 break; |
1120 case WINDOW_UPDATE: | 1008 case WINDOW_UPDATE: |
1121 if (current_frame_length_ != GetWindowUpdateSize()) { | 1009 if (current_frame_length_ != GetWindowUpdateSize()) { |
1122 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 1010 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1123 } else if (current_frame_flags_ != 0) { | 1011 } else if (current_frame_flags_ != 0) { |
1124 VLOG(1) << "Undefined frame flags for WINDOW_UPDATE frame: " << hex | 1012 VLOG(1) << "Undefined frame flags for WINDOW_UPDATE frame: " << hex |
1125 << static_cast<int>(current_frame_flags_); | 1013 << static_cast<int>(current_frame_flags_); |
1126 current_frame_flags_ = 0; | 1014 current_frame_flags_ = 0; |
1127 } | 1015 } |
1128 break; | 1016 break; |
1129 case BLOCKED: | 1017 case BLOCKED: |
1130 if (protocol_version_ == SPDY3 || | 1018 if (current_frame_length_ != GetBlockedSize()) { |
1131 current_frame_length_ != GetBlockedSize()) { | |
1132 set_error(SPDY_INVALID_CONTROL_FRAME); | 1019 set_error(SPDY_INVALID_CONTROL_FRAME); |
1133 } else if (current_frame_flags_ != 0) { | 1020 } else if (current_frame_flags_ != 0) { |
1134 VLOG(1) << "Undefined frame flags for BLOCKED frame: " << hex | 1021 VLOG(1) << "Undefined frame flags for BLOCKED frame: " << hex |
1135 << static_cast<int>(current_frame_flags_); | 1022 << static_cast<int>(current_frame_flags_); |
1136 current_frame_flags_ = 0; | 1023 current_frame_flags_ = 0; |
1137 } | 1024 } |
1138 break; | 1025 break; |
1139 case PUSH_PROMISE: | 1026 case PUSH_PROMISE: |
1140 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 1027 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
1141 set_error(SPDY_INVALID_CONTROL_FRAME); | 1028 set_error(SPDY_INVALID_CONTROL_FRAME); |
1142 } else if (protocol_version_ == SPDY3 && current_frame_flags_ != 0) { | |
1143 VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex | |
1144 << static_cast<int>(current_frame_flags_); | |
1145 current_frame_flags_ = 0; | |
1146 } else if (protocol_version_ == HTTP2 && | 1029 } else if (protocol_version_ == HTTP2 && |
1147 current_frame_flags_ & | 1030 current_frame_flags_ & |
1148 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | | 1031 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | |
1149 HEADERS_FLAG_PADDED)) { | 1032 HEADERS_FLAG_PADDED)) { |
1150 VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex | 1033 VLOG(1) << "Undefined frame flags for PUSH_PROMISE frame: " << hex |
1151 << static_cast<int>(current_frame_flags_); | 1034 << static_cast<int>(current_frame_flags_); |
1152 current_frame_flags_ &= | 1035 current_frame_flags_ &= |
1153 (PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED); | 1036 (PUSH_PROMISE_FLAG_END_PUSH_PROMISE | HEADERS_FLAG_PADDED); |
1154 } | 1037 } |
1155 break; | 1038 break; |
1156 case CONTINUATION: | 1039 case CONTINUATION: |
1157 if (protocol_version_ == SPDY3 || | 1040 if (current_frame_length_ < GetContinuationMinimumSize()) { |
1158 current_frame_length_ < GetContinuationMinimumSize()) { | |
1159 set_error(SPDY_INVALID_CONTROL_FRAME); | 1041 set_error(SPDY_INVALID_CONTROL_FRAME); |
1160 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 1042 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
1161 VLOG(1) << "Undefined frame flags for CONTINUATION frame: " << hex | 1043 VLOG(1) << "Undefined frame flags for CONTINUATION frame: " << hex |
1162 << static_cast<int>(current_frame_flags_); | 1044 << static_cast<int>(current_frame_flags_); |
1163 current_frame_flags_ &= HEADERS_FLAG_END_HEADERS; | 1045 current_frame_flags_ &= HEADERS_FLAG_END_HEADERS; |
1164 } | 1046 } |
1165 break; | 1047 break; |
1166 case ALTSVC: | 1048 case ALTSVC: |
1167 if (current_frame_length_ <= GetAltSvcMinimumSize()) { | 1049 if (current_frame_length_ <= GetAltSvcMinimumSize()) { |
1168 set_error(SPDY_INVALID_CONTROL_FRAME); | 1050 set_error(SPDY_INVALID_CONTROL_FRAME); |
1169 } else if (current_frame_flags_ != 0) { | 1051 } else if (current_frame_flags_ != 0) { |
1170 VLOG(1) << "Undefined frame flags for ALTSVC frame: " << hex | 1052 VLOG(1) << "Undefined frame flags for ALTSVC frame: " << hex |
1171 << static_cast<int>(current_frame_flags_); | 1053 << static_cast<int>(current_frame_flags_); |
1172 current_frame_flags_ = 0; | 1054 current_frame_flags_ = 0; |
1173 } | 1055 } |
1174 break; | 1056 break; |
1175 case PRIORITY: | 1057 case PRIORITY: |
1176 if (protocol_version_ == SPDY3 || | 1058 if (current_frame_length_ != GetPrioritySize()) { |
1177 current_frame_length_ != GetPrioritySize()) { | |
1178 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); | 1059 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); |
1179 } else if (current_frame_flags_ != 0) { | 1060 } else if (current_frame_flags_ != 0) { |
1180 VLOG(1) << "Undefined frame flags for PRIORITY frame: " << hex | 1061 VLOG(1) << "Undefined frame flags for PRIORITY frame: " << hex |
1181 << static_cast<int>(current_frame_flags_); | 1062 << static_cast<int>(current_frame_flags_); |
1182 current_frame_flags_ = 0; | 1063 current_frame_flags_ = 0; |
1183 } | 1064 } |
1184 break; | 1065 break; |
1185 default: | 1066 default: |
1186 LOG(WARNING) << "Valid " << display_protocol_ | 1067 LOG(WARNING) << "Valid " << display_protocol_ |
1187 << " control frame with unhandled type: " | 1068 << " control frame with unhandled type: " |
1188 << current_frame_type_; | 1069 << current_frame_type_; |
1189 // This branch should be unreachable because of the frame type bounds | 1070 // This branch should be unreachable because of the frame type bounds |
1190 // check above. However, we DLOG(FATAL) here in an effort to painfully | 1071 // check above. However, we DLOG(FATAL) here in an effort to painfully |
1191 // club the head of the developer who failed to keep this file in sync | 1072 // club the head of the developer who failed to keep this file in sync |
1192 // with spdy_protocol.h. | 1073 // with spdy_protocol.h. |
1193 set_error(SPDY_INVALID_CONTROL_FRAME); | 1074 set_error(SPDY_INVALID_CONTROL_FRAME); |
1194 DLOG(FATAL); | 1075 DLOG(FATAL); |
1195 break; | 1076 break; |
1196 } | 1077 } |
1197 | 1078 |
1198 if (state_ == SPDY_ERROR) { | 1079 if (state_ == SPDY_ERROR) { |
1199 return; | 1080 return; |
1200 } | 1081 } |
1201 | 1082 |
1202 if (protocol_version_ == SPDY3 && | |
1203 current_frame_length_ > | |
1204 kSpdyInitialFrameSizeLimit + | |
1205 SpdyConstants::GetFrameHeaderSize(protocol_version_)) { | |
1206 DLOG(WARNING) << "Received control frame of type " << current_frame_type_ | |
1207 << " with way too big of a payload: " | |
1208 << current_frame_length_; | |
1209 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); | |
1210 return; | |
1211 } | |
1212 | |
1213 if (current_frame_type_ == GOAWAY) { | 1083 if (current_frame_type_ == GOAWAY) { |
1214 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); | 1084 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); |
1215 return; | 1085 return; |
1216 } | 1086 } |
1217 | 1087 |
1218 if (current_frame_type_ == RST_STREAM) { | 1088 if (current_frame_type_ == RST_STREAM) { |
1219 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD); | 1089 CHANGE_STATE(SPDY_RST_STREAM_FRAME_PAYLOAD); |
1220 return; | 1090 return; |
1221 } | 1091 } |
1222 | 1092 |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1511 remaining_data_length_ -= bytes_read; | 1381 remaining_data_length_ -= bytes_read; |
1512 } | 1382 } |
1513 | 1383 |
1514 if (remaining_control_header_ == 0) { | 1384 if (remaining_control_header_ == 0) { |
1515 SpdyFrameReader reader(current_frame_buffer_.data(), | 1385 SpdyFrameReader reader(current_frame_buffer_.data(), |
1516 current_frame_buffer_.len()); | 1386 current_frame_buffer_.len()); |
1517 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. | 1387 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. |
1518 | 1388 |
1519 switch (current_frame_type_) { | 1389 switch (current_frame_type_) { |
1520 case SYN_STREAM: | 1390 case SYN_STREAM: |
1521 { | 1391 // TODO(alyssar) remove SYN_STREAM, SYN_REPLY and all associated calls. |
1522 DCHECK_EQ(SPDY3, protocol_version_); | 1392 DCHECK(false); |
1523 bool successful_read = true; | |
1524 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
1525 DCHECK(successful_read); | |
1526 if (current_frame_stream_id_ == 0) { | |
1527 set_error(SPDY_INVALID_CONTROL_FRAME); | |
1528 return original_len - len; | |
1529 } | |
1530 | |
1531 SpdyStreamId associated_to_stream_id = kInvalidStream; | |
1532 successful_read = reader.ReadUInt31(&associated_to_stream_id); | |
1533 DCHECK(successful_read); | |
1534 | |
1535 SpdyPriority priority = 0; | |
1536 successful_read = reader.ReadUInt8(&priority); | |
1537 DCHECK(successful_read); | |
1538 priority = priority >> 5; | |
1539 | |
1540 // Seek past unused byte. | |
1541 reader.Seek(1); | |
1542 | |
1543 DCHECK(reader.IsDoneReading()); | |
1544 if (debug_visitor_) { | |
1545 debug_visitor_->OnReceiveCompressedFrame( | |
1546 current_frame_stream_id_, | |
1547 current_frame_type_, | |
1548 current_frame_length_); | |
1549 } | |
1550 visitor_->OnSynStream( | |
1551 current_frame_stream_id_, | |
1552 associated_to_stream_id, | |
1553 priority, | |
1554 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, | |
1555 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); | |
1556 } | |
1557 break; | 1393 break; |
1558 case SYN_REPLY: | 1394 case SYN_REPLY: |
1559 DCHECK_EQ(SPDY3, protocol_version_); | 1395 DCHECK(false); |
1560 /* FALLTHROUGH */ | 1396 break; |
1561 case HEADERS: | 1397 case HEADERS: |
1562 // SYN_REPLY and HEADERS are the same, save for the visitor call. | 1398 // SYN_REPLY and HEADERS are the same, save for the visitor call. |
1563 { | 1399 { |
1564 bool successful_read = true; | 1400 bool successful_read = true; |
1565 if (protocol_version_ == SPDY3) { | |
1566 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
1567 DCHECK(successful_read); | |
1568 } | |
1569 if (current_frame_stream_id_ == 0) { | 1401 if (current_frame_stream_id_ == 0) { |
1570 set_error(SPDY_INVALID_CONTROL_FRAME); | 1402 set_error(SPDY_INVALID_CONTROL_FRAME); |
1571 return original_len - len; | 1403 return original_len - len; |
1572 } | 1404 } |
1573 if (protocol_version_ == HTTP2 && | 1405 if (protocol_version_ == HTTP2 && |
1574 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && | 1406 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && |
1575 current_frame_type_ == HEADERS) { | 1407 current_frame_type_ == HEADERS) { |
1576 expect_continuation_ = current_frame_stream_id_; | 1408 expect_continuation_ = current_frame_stream_id_; |
1577 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1409 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
1578 } | 1410 } |
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1700 #endif | 1532 #endif |
1701 } | 1533 } |
1702 | 1534 |
1703 if (current_frame_type_ != CONTINUATION) { | 1535 if (current_frame_type_ != CONTINUATION) { |
1704 header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_); | 1536 header_handler_ = visitor_->OnHeaderFrameStart(current_frame_stream_id_); |
1705 if (header_handler_ == nullptr) { | 1537 if (header_handler_ == nullptr) { |
1706 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; | 1538 SPDY_BUG << "visitor_->OnHeaderFrameStart returned nullptr"; |
1707 set_error(SPDY_INTERNAL_FRAMER_ERROR); | 1539 set_error(SPDY_INTERNAL_FRAMER_ERROR); |
1708 return original_len - len; | 1540 return original_len - len; |
1709 } | 1541 } |
1710 if (protocol_version() == SPDY3) { | 1542 GetHpackDecoder()->HandleControlFrameHeadersStart(header_handler_); |
1711 header_parser_.reset( | |
1712 new SpdyHeadersBlockParser(protocol_version(), header_handler_)); | |
1713 } else { | |
1714 GetHpackDecoder()->HandleControlFrameHeadersStart(header_handler_); | |
1715 } | |
1716 } | 1543 } |
1717 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | 1544 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
1718 } | 1545 } |
1719 return original_len - len; | 1546 return original_len - len; |
1720 } | 1547 } |
1721 | 1548 |
1722 // Does not buffer the control payload. Instead, either passes directly to the | 1549 // Does not buffer the control payload. Instead, either passes directly to the |
1723 // visitor or decompresses and then passes directly to the visitor, via | 1550 // visitor or decompresses and then passes directly to the visitor, via |
1724 // IncrementallyDeliverControlFrameHeaderData() or | 1551 // IncrementallyDeliverControlFrameHeaderData() or |
1725 // IncrementallyDecompressControlFrameHeaderData() respectively. | 1552 // IncrementallyDecompressControlFrameHeaderData() respectively. |
(...skipping 19 matching lines...) Expand all Loading... |
1745 size_t process_bytes = std::min( | 1572 size_t process_bytes = std::min( |
1746 data_len, remaining_data_length_ - remaining_padding_payload_length_); | 1573 data_len, remaining_data_length_ - remaining_padding_payload_length_); |
1747 if (is_hpack_header_block) { | 1574 if (is_hpack_header_block) { |
1748 if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, | 1575 if (!GetHpackDecoder()->HandleControlFrameHeadersData(data, |
1749 process_bytes)) { | 1576 process_bytes)) { |
1750 // TODO(jgraettinger): Finer-grained HPACK error codes. | 1577 // TODO(jgraettinger): Finer-grained HPACK error codes. |
1751 set_error(SPDY_DECOMPRESS_FAILURE); | 1578 set_error(SPDY_DECOMPRESS_FAILURE); |
1752 processed_successfully = false; | 1579 processed_successfully = false; |
1753 } | 1580 } |
1754 } else if (process_bytes > 0) { | 1581 } else if (process_bytes > 0) { |
1755 if (protocol_version_ == SPDY3 && enable_compression_) { | 1582 processed_successfully = IncrementallyDeliverControlFrameHeaderData( |
1756 processed_successfully = IncrementallyDecompressControlFrameHeaderData( | 1583 current_frame_stream_id_, data, process_bytes); |
1757 current_frame_stream_id_, data, process_bytes); | |
1758 } else { | |
1759 processed_successfully = IncrementallyDeliverControlFrameHeaderData( | |
1760 current_frame_stream_id_, data, process_bytes); | |
1761 } | |
1762 } | 1584 } |
1763 remaining_data_length_ -= process_bytes; | 1585 remaining_data_length_ -= process_bytes; |
1764 | 1586 |
1765 // Handle the case that there is no futher data in this frame. | 1587 // Handle the case that there is no futher data in this frame. |
1766 if (remaining_data_length_ == remaining_padding_payload_length_ && | 1588 if (remaining_data_length_ == remaining_padding_payload_length_ && |
1767 processed_successfully) { | 1589 processed_successfully) { |
1768 if (expect_continuation_ == 0) { | 1590 if (expect_continuation_ == 0) { |
1769 if (is_hpack_header_block) { | 1591 if (is_hpack_header_block) { |
1770 size_t compressed_len = 0; | 1592 size_t compressed_len = 0; |
1771 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( | 1593 if (GetHpackDecoder()->HandleControlFrameHeadersComplete( |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1824 return bytes_read; | 1646 return bytes_read; |
1825 } | 1647 } |
1826 | 1648 |
1827 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, | 1649 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, |
1828 size_t data_len) { | 1650 size_t data_len) { |
1829 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); | 1651 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); |
1830 DCHECK_EQ(SETTINGS, current_frame_type_); | 1652 DCHECK_EQ(SETTINGS, current_frame_type_); |
1831 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); | 1653 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); |
1832 size_t processed_bytes = 0; | 1654 size_t processed_bytes = 0; |
1833 | 1655 |
1834 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version_); | 1656 size_t setting_size = 6; |
1835 | 1657 |
1836 // Loop over our incoming data. | 1658 // Loop over our incoming data. |
1837 while (unprocessed_bytes > 0) { | 1659 while (unprocessed_bytes > 0) { |
1838 // Process up to one setting at a time. | 1660 // Process up to one setting at a time. |
1839 size_t processing = std::min(unprocessed_bytes, | 1661 size_t processing = std::min(unprocessed_bytes, |
1840 setting_size - settings_scratch_.buffer.len()); | 1662 setting_size - settings_scratch_.buffer.len()); |
1841 | 1663 |
1842 // Check if we have a complete setting in our input. | 1664 // Check if we have a complete setting in our input. |
1843 if (processing == setting_size) { | 1665 if (processing == setting_size) { |
1844 // Parse the setting directly out of the input without buffering. | 1666 // Parse the setting directly out of the input without buffering. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1877 } | 1699 } |
1878 | 1700 |
1879 bool SpdyFramer::ProcessSetting(const char* data) { | 1701 bool SpdyFramer::ProcessSetting(const char* data) { |
1880 int id_field; | 1702 int id_field; |
1881 SpdySettingsIds id; | 1703 SpdySettingsIds id; |
1882 uint8_t flags = 0; | 1704 uint8_t flags = 0; |
1883 uint32_t value; | 1705 uint32_t value; |
1884 | 1706 |
1885 // Extract fields. | 1707 // Extract fields. |
1886 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 1708 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
1887 if (protocol_version_ == SPDY3) { | 1709 id_field = base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data))); |
1888 const uint32_t id_and_flags_wire = | 1710 value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 2))); |
1889 *(reinterpret_cast<const uint32_t*>(data)); | |
1890 SettingsFlagsAndId id_and_flags = SettingsFlagsAndId::FromWireFormat( | |
1891 protocol_version_, id_and_flags_wire); | |
1892 id_field = id_and_flags.id(); | |
1893 flags = id_and_flags.flags(); | |
1894 value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 4))); | |
1895 } else { | |
1896 id_field = base::NetToHost16(*(reinterpret_cast<const uint16_t*>(data))); | |
1897 value = base::NetToHost32(*(reinterpret_cast<const uint32_t*>(data + 2))); | |
1898 } | |
1899 | 1711 |
1900 // Validate id. | 1712 // Validate id. |
1901 if (!SpdyConstants::IsValidSettingId(protocol_version_, id_field)) { | 1713 if (!SpdyConstants::IsValidSettingId(protocol_version_, id_field)) { |
1902 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1714 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
1903 if (protocol_version_ == SPDY3) { | 1715 // In HTTP2 we ignore unknown settings for extensibility. |
1904 return false; | 1716 return true; |
1905 } else { | |
1906 // In HTTP2 we ignore unknown settings for extensibility. | |
1907 return true; | |
1908 } | |
1909 } | 1717 } |
1910 id = SpdyConstants::ParseSettingId(protocol_version_, id_field); | 1718 id = SpdyConstants::ParseSettingId(protocol_version_, id_field); |
1911 | 1719 |
1912 if (protocol_version_ == SPDY3) { | |
1913 // Detect duplicates. | |
1914 if (id <= settings_scratch_.last_setting_id) { | |
1915 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id | |
1916 << " in " << display_protocol_ << " SETTINGS frame " | |
1917 << "(last setting id was " | |
1918 << settings_scratch_.last_setting_id << ")."; | |
1919 return false; | |
1920 } | |
1921 settings_scratch_.last_setting_id = id; | |
1922 | |
1923 // Validate flags. | |
1924 uint8_t kFlagsMask = SETTINGS_FLAG_PLEASE_PERSIST | SETTINGS_FLAG_PERSISTED; | |
1925 if ((flags & ~(kFlagsMask)) != 0) { | |
1926 DLOG(WARNING) << "Unknown SETTINGS flags provided for id " << id << ": " | |
1927 << flags; | |
1928 return false; | |
1929 } | |
1930 } | |
1931 | |
1932 // Validation succeeded. Pass on to visitor. | 1720 // Validation succeeded. Pass on to visitor. |
1933 visitor_->OnSetting(id, flags, value); | 1721 visitor_->OnSetting(id, flags, value); |
1934 return true; | 1722 return true; |
1935 } | 1723 } |
1936 | 1724 |
1937 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { | 1725 size_t SpdyFramer::ProcessControlFramePayload(const char* data, size_t len) { |
1938 size_t original_len = len; | 1726 size_t original_len = len; |
1939 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, | 1727 size_t bytes_read = UpdateCurrentFrameBuffer(&data, &len, |
1940 remaining_data_length_); | 1728 remaining_data_length_); |
1941 remaining_data_length_ -= bytes_read; | 1729 remaining_data_length_ -= bytes_read; |
1942 if (remaining_data_length_ == 0) { | 1730 if (remaining_data_length_ == 0) { |
1943 SpdyFrameReader reader(current_frame_buffer_.data(), | 1731 SpdyFrameReader reader(current_frame_buffer_.data(), |
1944 current_frame_buffer_.len()); | 1732 current_frame_buffer_.len()); |
1945 reader.Seek(GetFrameHeaderSize()); // Skip frame header. | 1733 reader.Seek(GetFrameHeaderSize()); // Skip frame header. |
1946 | 1734 |
1947 // Use frame-specific handlers. | 1735 // Use frame-specific handlers. |
1948 switch (current_frame_type_) { | 1736 switch (current_frame_type_) { |
1949 case PING: { | 1737 case PING: { |
1950 SpdyPingId id = 0; | 1738 SpdyPingId id = 0; |
1951 bool is_ack = protocol_version_ == HTTP2 && | 1739 bool is_ack = protocol_version_ == HTTP2 && |
1952 (current_frame_flags_ & PING_FLAG_ACK); | 1740 (current_frame_flags_ & PING_FLAG_ACK); |
1953 bool successful_read = true; | 1741 bool successful_read = true; |
1954 if (protocol_version_ == SPDY3) { | 1742 successful_read = reader.ReadUInt64(&id); |
1955 uint32_t id32 = 0; | |
1956 successful_read = reader.ReadUInt32(&id32); | |
1957 id = id32; | |
1958 } else { | |
1959 successful_read = reader.ReadUInt64(&id); | |
1960 } | |
1961 DCHECK(successful_read); | 1743 DCHECK(successful_read); |
1962 DCHECK(reader.IsDoneReading()); | 1744 DCHECK(reader.IsDoneReading()); |
1963 visitor_->OnPing(id, is_ack); | 1745 visitor_->OnPing(id, is_ack); |
1964 } | 1746 } |
1965 break; | 1747 break; |
1966 case WINDOW_UPDATE: { | 1748 case WINDOW_UPDATE: { |
1967 uint32_t delta_window_size = 0; | 1749 uint32_t delta_window_size = 0; |
1968 bool successful_read = true; | 1750 bool successful_read = true; |
1969 if (protocol_version_ == SPDY3) { | |
1970 successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
1971 DCHECK(successful_read); | |
1972 } | |
1973 successful_read = reader.ReadUInt32(&delta_window_size); | 1751 successful_read = reader.ReadUInt32(&delta_window_size); |
1974 DCHECK(successful_read); | 1752 DCHECK(successful_read); |
1975 DCHECK(reader.IsDoneReading()); | 1753 DCHECK(reader.IsDoneReading()); |
1976 visitor_->OnWindowUpdate(current_frame_stream_id_, | 1754 visitor_->OnWindowUpdate(current_frame_stream_id_, |
1977 delta_window_size); | 1755 delta_window_size); |
1978 } | 1756 } |
1979 break; | 1757 break; |
1980 case BLOCKED: { | 1758 case BLOCKED: { |
1981 DCHECK_EQ(HTTP2, protocol_version_); | 1759 DCHECK_EQ(HTTP2, protocol_version_); |
1982 DCHECK(reader.IsDoneReading()); | 1760 DCHECK(reader.IsDoneReading()); |
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2095 if (!already_parsed_header) { | 1873 if (!already_parsed_header) { |
2096 // Buffer the new RST_STREAM header bytes we got. | 1874 // Buffer the new RST_STREAM header bytes we got. |
2097 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes); | 1875 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes); |
2098 | 1876 |
2099 // Do we have enough to parse the constant size RST_STREAM header? | 1877 // Do we have enough to parse the constant size RST_STREAM header? |
2100 if (current_frame_buffer_.len() == header_size) { | 1878 if (current_frame_buffer_.len() == header_size) { |
2101 // Parse out the last good stream id. | 1879 // Parse out the last good stream id. |
2102 SpdyFrameReader reader(current_frame_buffer_.data(), | 1880 SpdyFrameReader reader(current_frame_buffer_.data(), |
2103 current_frame_buffer_.len()); | 1881 current_frame_buffer_.len()); |
2104 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. | 1882 reader.Seek(GetFrameHeaderSize()); // Seek past frame header. |
2105 if (protocol_version_ == SPDY3) { | |
2106 bool successful_read = reader.ReadUInt31(¤t_frame_stream_id_); | |
2107 DCHECK(successful_read); | |
2108 } | |
2109 | 1883 |
2110 SpdyRstStreamStatus status = RST_STREAM_NO_ERROR; | 1884 SpdyRstStreamStatus status = RST_STREAM_NO_ERROR; |
2111 uint32_t status_raw = status; | 1885 uint32_t status_raw = status; |
2112 bool successful_read = reader.ReadUInt32(&status_raw); | 1886 bool successful_read = reader.ReadUInt32(&status_raw); |
2113 DCHECK(successful_read); | 1887 DCHECK(successful_read); |
2114 if (SpdyConstants::IsValidRstStreamStatus(protocol_version_, | 1888 if (SpdyConstants::IsValidRstStreamStatus(protocol_version_, |
2115 status_raw)) { | 1889 status_raw)) { |
2116 status = | 1890 status = |
2117 SpdyConstants::ParseRstStreamStatus(protocol_version_, status_raw); | 1891 SpdyConstants::ParseRstStreamStatus(protocol_version_, status_raw); |
2118 } else { | 1892 } else { |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2222 } | 1996 } |
2223 | 1997 |
2224 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { | 1998 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { |
2225 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); | 1999 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); |
2226 | 2000 |
2227 size_t original_len = len; | 2001 size_t original_len = len; |
2228 if (remaining_padding_payload_length_ > 0) { | 2002 if (remaining_padding_payload_length_ > 0) { |
2229 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); | 2003 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); |
2230 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); | 2004 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len); |
2231 if (current_frame_type_ == DATA && amount_to_discard > 0) { | 2005 if (current_frame_type_ == DATA && amount_to_discard > 0) { |
2232 SPDY_BUG_IF(protocol_version_ == SPDY3) | |
2233 << "Padding invalid for SPDY version " << protocol_version_; | |
2234 visitor_->OnStreamPadding(current_frame_stream_id_, amount_to_discard); | 2006 visitor_->OnStreamPadding(current_frame_stream_id_, amount_to_discard); |
2235 } | 2007 } |
2236 data += amount_to_discard; | 2008 data += amount_to_discard; |
2237 len -= amount_to_discard; | 2009 len -= amount_to_discard; |
2238 remaining_padding_payload_length_ -= amount_to_discard; | 2010 remaining_padding_payload_length_ -= amount_to_discard; |
2239 remaining_data_length_ -= amount_to_discard; | 2011 remaining_data_length_ -= amount_to_discard; |
2240 } | 2012 } |
2241 | 2013 |
2242 if (remaining_data_length_ == 0) { | 2014 if (remaining_data_length_ == 0) { |
2243 // If the FIN flag is set, or this ends a header block which set FIN, | 2015 // If the FIN flag is set, or this ends a header block which set FIN, |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2405 return framer_->SerializeContinuation(continuation_ir); | 2177 return framer_->SerializeContinuation(continuation_ir); |
2406 } | 2178 } |
2407 } | 2179 } |
2408 | 2180 |
2409 SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const { | 2181 SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const { |
2410 uint8_t flags = DATA_FLAG_NONE; | 2182 uint8_t flags = DATA_FLAG_NONE; |
2411 if (data_ir.fin()) { | 2183 if (data_ir.fin()) { |
2412 flags = DATA_FLAG_FIN; | 2184 flags = DATA_FLAG_FIN; |
2413 } | 2185 } |
2414 | 2186 |
2415 if (protocol_version_ == SPDY3) { | 2187 int num_padding_fields = 0; |
2416 const size_t size = GetDataFrameMinimumSize() + data_ir.data_len(); | 2188 if (data_ir.padded()) { |
2417 SpdyFrameBuilder builder(size, protocol_version_); | 2189 flags |= DATA_FLAG_PADDED; |
2418 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2190 ++num_padding_fields; |
2419 builder.WriteBytes(data_ir.data(), data_ir.data_len()); | 2191 } |
2420 DCHECK_EQ(size, builder.length()); | |
2421 return builder.take(); | |
2422 } else { | |
2423 int num_padding_fields = 0; | |
2424 if (data_ir.padded()) { | |
2425 flags |= DATA_FLAG_PADDED; | |
2426 ++num_padding_fields; | |
2427 } | |
2428 | 2192 |
2429 const size_t size_with_padding = num_padding_fields + data_ir.data_len() + | 2193 const size_t size_with_padding = num_padding_fields + data_ir.data_len() + |
2430 data_ir.padding_payload_len() + | 2194 data_ir.padding_payload_len() + |
2431 GetDataFrameMinimumSize(); | 2195 GetDataFrameMinimumSize(); |
2432 SpdyFrameBuilder builder(size_with_padding, protocol_version_); | 2196 SpdyFrameBuilder builder(size_with_padding, protocol_version_); |
2433 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2197 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
2434 if (data_ir.padded()) { | 2198 if (data_ir.padded()) { |
2435 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2199 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
2436 } | |
2437 builder.WriteBytes(data_ir.data(), data_ir.data_len()); | |
2438 if (data_ir.padding_payload_len() > 0) { | |
2439 string padding(data_ir.padding_payload_len(), 0); | |
2440 builder.WriteBytes(padding.data(), padding.length()); | |
2441 } | |
2442 DCHECK_EQ(size_with_padding, builder.length()); | |
2443 return builder.take(); | |
2444 } | 2200 } |
| 2201 builder.WriteBytes(data_ir.data(), data_ir.data_len()); |
| 2202 if (data_ir.padding_payload_len() > 0) { |
| 2203 string padding(data_ir.padding_payload_len(), 0); |
| 2204 builder.WriteBytes(padding.data(), padding.length()); |
| 2205 } |
| 2206 DCHECK_EQ(size_with_padding, builder.length()); |
| 2207 return builder.take(); |
2445 } | 2208 } |
2446 | 2209 |
2447 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 2210 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( |
2448 const SpdyDataIR& data_ir) const { | 2211 const SpdyDataIR& data_ir) const { |
2449 uint8_t flags = DATA_FLAG_NONE; | 2212 uint8_t flags = DATA_FLAG_NONE; |
2450 if (data_ir.fin()) { | 2213 if (data_ir.fin()) { |
2451 flags = DATA_FLAG_FIN; | 2214 flags = DATA_FLAG_FIN; |
2452 } | 2215 } |
2453 | 2216 |
2454 size_t frame_size = GetDataFrameMinimumSize(); | 2217 size_t frame_size = GetDataFrameMinimumSize(); |
(...skipping 16 matching lines...) Expand all Loading... |
2471 data_ir.padding_payload_len()); | 2234 data_ir.padding_payload_len()); |
2472 } else { | 2235 } else { |
2473 builder.OverwriteLength(*this, data_ir.data_len()); | 2236 builder.OverwriteLength(*this, data_ir.data_len()); |
2474 } | 2237 } |
2475 DCHECK_EQ(frame_size, builder.length()); | 2238 DCHECK_EQ(frame_size, builder.length()); |
2476 return builder.take(); | 2239 return builder.take(); |
2477 } | 2240 } |
2478 | 2241 |
2479 SpdySerializedFrame SpdyFramer::SerializeSynStream( | 2242 SpdySerializedFrame SpdyFramer::SerializeSynStream( |
2480 const SpdySynStreamIR& syn_stream) { | 2243 const SpdySynStreamIR& syn_stream) { |
2481 DCHECK_EQ(SPDY3, protocol_version_); | 2244 // TODO(alyssar) remove this entirely |
| 2245 DCHECK(false); |
2482 uint8_t flags = 0; | 2246 uint8_t flags = 0; |
2483 if (syn_stream.fin()) { | 2247 if (syn_stream.fin()) { |
2484 flags |= CONTROL_FLAG_FIN; | 2248 flags |= CONTROL_FLAG_FIN; |
2485 } | 2249 } |
2486 if (syn_stream.unidirectional()) { | 2250 if (syn_stream.unidirectional()) { |
2487 flags |= CONTROL_FLAG_UNIDIRECTIONAL; | 2251 flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
2488 } | 2252 } |
2489 | 2253 |
2490 // Sanitize priority. | 2254 // Sanitize priority. |
2491 uint8_t priority = syn_stream.priority(); | 2255 uint8_t priority = syn_stream.priority(); |
(...skipping 22 matching lines...) Expand all Loading... |
2514 SYN_STREAM, | 2278 SYN_STREAM, |
2515 payload_len, | 2279 payload_len, |
2516 builder.length()); | 2280 builder.length()); |
2517 } | 2281 } |
2518 | 2282 |
2519 return builder.take(); | 2283 return builder.take(); |
2520 } | 2284 } |
2521 | 2285 |
2522 SpdySerializedFrame SpdyFramer::SerializeSynReply( | 2286 SpdySerializedFrame SpdyFramer::SerializeSynReply( |
2523 const SpdySynReplyIR& syn_reply) { | 2287 const SpdySynReplyIR& syn_reply) { |
2524 DCHECK_EQ(SPDY3, protocol_version_); | 2288 // TODO(alyssar) remove this entirely |
| 2289 DCHECK(false); |
2525 uint8_t flags = 0; | 2290 uint8_t flags = 0; |
2526 if (syn_reply.fin()) { | 2291 if (syn_reply.fin()) { |
2527 flags |= CONTROL_FLAG_FIN; | 2292 flags |= CONTROL_FLAG_FIN; |
2528 } | 2293 } |
2529 | 2294 |
2530 // The size of this frame, including variable-length header block. | 2295 // The size of this frame, including variable-length header block. |
2531 const size_t size = | 2296 const size_t size = |
2532 GetSynReplyMinimumSize() + GetSerializedLength(syn_reply.header_block()); | 2297 GetSynReplyMinimumSize() + GetSerializedLength(syn_reply.header_block()); |
2533 | 2298 |
2534 SpdyFrameBuilder builder(size, protocol_version_); | 2299 SpdyFrameBuilder builder(size, protocol_version_); |
(...skipping 17 matching lines...) Expand all Loading... |
2552 SpdySerializedFrame SpdyFramer::SerializeRstStream( | 2317 SpdySerializedFrame SpdyFramer::SerializeRstStream( |
2553 const SpdyRstStreamIR& rst_stream) const { | 2318 const SpdyRstStreamIR& rst_stream) const { |
2554 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM | 2319 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM |
2555 // payloads, but will not emit them. This is used for draft HTTP/2, | 2320 // payloads, but will not emit them. This is used for draft HTTP/2, |
2556 // which doesn't currently include RST_STREAM payloads. GFE flags have been | 2321 // which doesn't currently include RST_STREAM payloads. GFE flags have been |
2557 // commented but left in place to simplify future patching. | 2322 // commented but left in place to simplify future patching. |
2558 // Compute the output buffer size, taking opaque data into account. | 2323 // Compute the output buffer size, taking opaque data into account. |
2559 size_t expected_length = GetRstStreamMinimumSize(); | 2324 size_t expected_length = GetRstStreamMinimumSize(); |
2560 SpdyFrameBuilder builder(expected_length, protocol_version_); | 2325 SpdyFrameBuilder builder(expected_length, protocol_version_); |
2561 | 2326 |
2562 // Serialize the RST_STREAM frame. | 2327 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); |
2563 if (protocol_version_ == SPDY3) { | |
2564 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); | |
2565 builder.WriteUInt32(rst_stream.stream_id()); | |
2566 } else { | |
2567 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); | |
2568 } | |
2569 | 2328 |
2570 builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus( | 2329 builder.WriteUInt32(SpdyConstants::SerializeRstStreamStatus( |
2571 protocol_version_, rst_stream.status())); | 2330 protocol_version_, rst_stream.status())); |
2572 | 2331 |
2573 DCHECK_EQ(expected_length, builder.length()); | 2332 DCHECK_EQ(expected_length, builder.length()); |
2574 return builder.take(); | 2333 return builder.take(); |
2575 } | 2334 } |
2576 | 2335 |
2577 SpdySerializedFrame SpdyFramer::SerializeSettings( | 2336 SpdySerializedFrame SpdyFramer::SerializeSettings( |
2578 const SpdySettingsIR& settings) const { | 2337 const SpdySettingsIR& settings) const { |
2579 uint8_t flags = 0; | 2338 uint8_t flags = 0; |
2580 | 2339 |
2581 if (protocol_version_ == SPDY3) { | 2340 if (settings.is_ack()) { |
2582 if (settings.clear_settings()) { | 2341 flags |= SETTINGS_FLAG_ACK; |
2583 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | |
2584 } | |
2585 } else { | |
2586 if (settings.is_ack()) { | |
2587 flags |= SETTINGS_FLAG_ACK; | |
2588 } | |
2589 } | 2342 } |
2590 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 2343 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
2591 | 2344 |
2592 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version_); | 2345 int setting_size = 6; |
2593 // Size, in bytes, of this SETTINGS frame. | 2346 // Size, in bytes, of this SETTINGS frame. |
2594 const size_t size = GetSettingsMinimumSize() + | 2347 const size_t size = GetSettingsMinimumSize() + |
2595 (values->size() * setting_size); | 2348 (values->size() * setting_size); |
2596 SpdyFrameBuilder builder(size, protocol_version_); | 2349 SpdyFrameBuilder builder(size, protocol_version_); |
2597 if (protocol_version_ == SPDY3) { | 2350 builder.BeginNewFrame(*this, SETTINGS, flags, 0); |
2598 builder.WriteControlFrameHeader(*this, SETTINGS, flags); | |
2599 } else { | |
2600 builder.BeginNewFrame(*this, SETTINGS, flags, 0); | |
2601 } | |
2602 | 2351 |
2603 // If this is an ACK, payload should be empty. | 2352 // If this is an ACK, payload should be empty. |
2604 if (protocol_version_ == HTTP2 && settings.is_ack()) { | 2353 if (protocol_version_ == HTTP2 && settings.is_ack()) { |
2605 return builder.take(); | 2354 return builder.take(); |
2606 } | 2355 } |
2607 | 2356 |
2608 if (protocol_version_ == SPDY3) { | |
2609 builder.WriteUInt32(values->size()); | |
2610 } | |
2611 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); | 2357 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); |
2612 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); | 2358 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); |
2613 it != values->end(); | 2359 it != values->end(); |
2614 ++it) { | 2360 ++it) { |
2615 int setting_id = | 2361 int setting_id = |
2616 SpdyConstants::SerializeSettingId(protocol_version_, it->first); | 2362 SpdyConstants::SerializeSettingId(protocol_version_, it->first); |
2617 DCHECK_GE(setting_id, 0); | 2363 DCHECK_GE(setting_id, 0); |
2618 if (protocol_version_ == SPDY3) { | 2364 builder.WriteUInt16(static_cast<uint16_t>(setting_id)); |
2619 uint8_t setting_flags = 0; | |
2620 if (it->second.persist_value) { | |
2621 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; | |
2622 } | |
2623 if (it->second.persisted) { | |
2624 setting_flags |= SETTINGS_FLAG_PERSISTED; | |
2625 } | |
2626 SettingsFlagsAndId flags_and_id(setting_flags, setting_id); | |
2627 uint32_t id_and_flags_wire = | |
2628 flags_and_id.GetWireFormat(protocol_version_); | |
2629 builder.WriteBytes(&id_and_flags_wire, 4); | |
2630 } else { | |
2631 builder.WriteUInt16(static_cast<uint16_t>(setting_id)); | |
2632 } | |
2633 builder.WriteUInt32(it->second.value); | 2365 builder.WriteUInt32(it->second.value); |
2634 } | 2366 } |
2635 DCHECK_EQ(size, builder.length()); | 2367 DCHECK_EQ(size, builder.length()); |
2636 return builder.take(); | 2368 return builder.take(); |
2637 } | 2369 } |
2638 | 2370 |
2639 SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 2371 SpdySerializedFrame SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
2640 SpdyFrameBuilder builder(GetPingSize(), protocol_version_); | 2372 SpdyFrameBuilder builder(GetPingSize(), protocol_version_); |
2641 if (protocol_version_ == SPDY3) { | 2373 uint8_t flags = 0; |
2642 builder.WriteControlFrameHeader(*this, PING, kNoFlags); | 2374 if (ping.is_ack()) { |
2643 builder.WriteUInt32(static_cast<uint32_t>(ping.id())); | 2375 flags |= PING_FLAG_ACK; |
2644 } else { | |
2645 uint8_t flags = 0; | |
2646 if (ping.is_ack()) { | |
2647 flags |= PING_FLAG_ACK; | |
2648 } | |
2649 builder.BeginNewFrame(*this, PING, flags, 0); | |
2650 builder.WriteUInt64(ping.id()); | |
2651 } | 2376 } |
| 2377 builder.BeginNewFrame(*this, PING, flags, 0); |
| 2378 builder.WriteUInt64(ping.id()); |
2652 DCHECK_EQ(GetPingSize(), builder.length()); | 2379 DCHECK_EQ(GetPingSize(), builder.length()); |
2653 return builder.take(); | 2380 return builder.take(); |
2654 } | 2381 } |
2655 | 2382 |
2656 SpdySerializedFrame SpdyFramer::SerializeGoAway( | 2383 SpdySerializedFrame SpdyFramer::SerializeGoAway( |
2657 const SpdyGoAwayIR& goaway) const { | 2384 const SpdyGoAwayIR& goaway) const { |
2658 // Compute the output buffer size, take opaque data into account. | 2385 // Compute the output buffer size, take opaque data into account. |
2659 size_t expected_length = GetGoAwayMinimumSize(); | 2386 size_t expected_length = GetGoAwayMinimumSize(); |
2660 if (protocol_version_ == HTTP2) { | 2387 if (protocol_version_ == HTTP2) { |
2661 expected_length += goaway.description().size(); | 2388 expected_length += goaway.description().size(); |
2662 } | 2389 } |
2663 SpdyFrameBuilder builder(expected_length, protocol_version_); | 2390 SpdyFrameBuilder builder(expected_length, protocol_version_); |
2664 | 2391 |
2665 // Serialize the GOAWAY frame. | 2392 // Serialize the GOAWAY frame. |
2666 if (protocol_version_ == SPDY3) { | 2393 builder.BeginNewFrame(*this, GOAWAY, 0, 0); |
2667 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); | |
2668 } else { | |
2669 builder.BeginNewFrame(*this, GOAWAY, 0, 0); | |
2670 } | |
2671 | 2394 |
2672 // GOAWAY frames specify the last good stream id for all SPDY versions. | 2395 // GOAWAY frames specify the last good stream id for all SPDY versions. |
2673 builder.WriteUInt32(goaway.last_good_stream_id()); | 2396 builder.WriteUInt32(goaway.last_good_stream_id()); |
2674 | 2397 |
2675 // GOAWAY frames also specify the error status code. | 2398 // GOAWAY frames also specify the error status code. |
2676 builder.WriteUInt32( | 2399 builder.WriteUInt32( |
2677 SpdyConstants::SerializeGoAwayStatus(protocol_version_, goaway.status())); | 2400 SpdyConstants::SerializeGoAwayStatus(protocol_version_, goaway.status())); |
2678 | 2401 |
2679 // In HTTP2, GOAWAY frames may also specify opaque data. | 2402 // In HTTP2, GOAWAY frames may also specify opaque data. |
2680 if ((protocol_version_ == HTTP2) && (goaway.description().size() > 0)) { | 2403 if ((protocol_version_ == HTTP2) && (goaway.description().size() > 0)) { |
(...skipping 30 matching lines...) Expand all Loading... |
2711 size += headers.padding_payload_len(); | 2434 size += headers.padding_payload_len(); |
2712 } | 2435 } |
2713 | 2436 |
2714 int weight = 0; | 2437 int weight = 0; |
2715 if (headers.has_priority()) { | 2438 if (headers.has_priority()) { |
2716 weight = ClampHttp2Weight(headers.weight()); | 2439 weight = ClampHttp2Weight(headers.weight()); |
2717 size += 5; | 2440 size += 5; |
2718 } | 2441 } |
2719 | 2442 |
2720 string hpack_encoding; | 2443 string hpack_encoding; |
2721 if (protocol_version_ == SPDY3) { | 2444 if (enable_compression_) { |
2722 size += GetSerializedLength(headers.header_block()); | 2445 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding); |
2723 } else { | 2446 } else { |
2724 if (enable_compression_) { | 2447 GetHpackEncoder()->EncodeHeaderSetWithoutCompression(headers.header_block(), |
2725 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), | 2448 &hpack_encoding); |
2726 &hpack_encoding); | 2449 } |
2727 } else { | 2450 size += hpack_encoding.size(); |
2728 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | 2451 if (size > kMaxControlFrameSize) { |
2729 headers.header_block(), &hpack_encoding); | 2452 size += GetNumberRequiredContinuationFrames(size) * |
2730 } | 2453 GetContinuationMinimumSize(); |
2731 size += hpack_encoding.size(); | 2454 flags &= ~HEADERS_FLAG_END_HEADERS; |
2732 if (size > kMaxControlFrameSize) { | |
2733 size += GetNumberRequiredContinuationFrames(size) * | |
2734 GetContinuationMinimumSize(); | |
2735 flags &= ~HEADERS_FLAG_END_HEADERS; | |
2736 } | |
2737 } | 2455 } |
2738 | 2456 |
2739 SpdyFrameBuilder builder(size, protocol_version_); | 2457 SpdyFrameBuilder builder(size, protocol_version_); |
2740 if (protocol_version_ == SPDY3) { | 2458 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); |
2741 builder.WriteControlFrameHeader(*this, HEADERS, flags); | |
2742 builder.WriteUInt32(headers.stream_id()); | |
2743 } else { | |
2744 builder.BeginNewFrame(*this, | |
2745 HEADERS, | |
2746 flags, | |
2747 headers.stream_id()); | |
2748 } | |
2749 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2459 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2750 | 2460 |
2751 if (protocol_version_ == SPDY3) { | 2461 int padding_payload_len = 0; |
2752 SerializeHeaderBlock(&builder, headers); | 2462 if (headers.padded()) { |
2753 } else { | 2463 builder.WriteUInt8(headers.padding_payload_len()); |
2754 int padding_payload_len = 0; | 2464 padding_payload_len = headers.padding_payload_len(); |
2755 if (headers.padded()) { | |
2756 builder.WriteUInt8(headers.padding_payload_len()); | |
2757 padding_payload_len = headers.padding_payload_len(); | |
2758 } | |
2759 if (headers.has_priority()) { | |
2760 builder.WriteUInt32(PackStreamDependencyValues( | |
2761 headers.exclusive(), headers.parent_stream_id())); | |
2762 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. | |
2763 builder.WriteUInt8(weight - 1); | |
2764 } | |
2765 WritePayloadWithContinuation(&builder, | |
2766 hpack_encoding, | |
2767 headers.stream_id(), | |
2768 HEADERS, | |
2769 padding_payload_len); | |
2770 } | 2465 } |
| 2466 if (headers.has_priority()) { |
| 2467 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
| 2468 headers.parent_stream_id())); |
| 2469 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. |
| 2470 builder.WriteUInt8(weight - 1); |
| 2471 } |
| 2472 WritePayloadWithContinuation(&builder, hpack_encoding, headers.stream_id(), |
| 2473 HEADERS, padding_payload_len); |
2771 | 2474 |
2772 if (debug_visitor_) { | 2475 if (debug_visitor_) { |
2773 // HTTP2 uses HPACK for header compression. However, continue to | 2476 // HTTP2 uses HPACK for header compression. However, continue to |
2774 // use GetSerializedLength() for an apples-to-apples comparision of | 2477 // use GetSerializedLength() for an apples-to-apples comparision of |
2775 // compression performance between HPACK and SPDY w/ deflate. | 2478 // compression performance between HPACK and SPDY w/ deflate. |
2776 const size_t payload_len = | 2479 const size_t payload_len = |
2777 GetSerializedLength(protocol_version_, &(headers.header_block())); | 2480 GetSerializedLength(protocol_version_, &(headers.header_block())); |
2778 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), | 2481 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), |
2779 HEADERS, | 2482 HEADERS, |
2780 payload_len, | 2483 payload_len, |
2781 builder.length()); | 2484 builder.length()); |
2782 } | 2485 } |
2783 | 2486 |
2784 return builder.take(); | 2487 return builder.take(); |
2785 } | 2488 } |
2786 | 2489 |
2787 SpdySerializedFrame SpdyFramer::SerializeWindowUpdate( | 2490 SpdySerializedFrame SpdyFramer::SerializeWindowUpdate( |
2788 const SpdyWindowUpdateIR& window_update) const { | 2491 const SpdyWindowUpdateIR& window_update) const { |
2789 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_); | 2492 SpdyFrameBuilder builder(GetWindowUpdateSize(), protocol_version_); |
2790 if (protocol_version_ == SPDY3) { | 2493 builder.BeginNewFrame(*this, WINDOW_UPDATE, kNoFlags, |
2791 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); | 2494 window_update.stream_id()); |
2792 builder.WriteUInt32(window_update.stream_id()); | |
2793 } else { | |
2794 builder.BeginNewFrame(*this, | |
2795 WINDOW_UPDATE, | |
2796 kNoFlags, | |
2797 window_update.stream_id()); | |
2798 } | |
2799 builder.WriteUInt32(window_update.delta()); | 2495 builder.WriteUInt32(window_update.delta()); |
2800 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2496 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
2801 return builder.take(); | 2497 return builder.take(); |
2802 } | 2498 } |
2803 | 2499 |
2804 SpdySerializedFrame SpdyFramer::SerializeBlocked( | 2500 SpdySerializedFrame SpdyFramer::SerializeBlocked( |
2805 const SpdyBlockedIR& blocked) const { | 2501 const SpdyBlockedIR& blocked) const { |
2806 DCHECK_EQ(HTTP2, protocol_version_); | 2502 DCHECK_EQ(HTTP2, protocol_version_); |
2807 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_); | 2503 SpdyFrameBuilder builder(GetBlockedSize(), protocol_version_); |
2808 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); | 2504 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); |
(...skipping 590 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3399 #else | 3095 #else |
3400 WriteHeaderBlockToZ(&frame.header_block(), compressor); | 3096 WriteHeaderBlockToZ(&frame.header_block(), compressor); |
3401 #endif // defined(USE_SYSTEM_ZLIB) | 3097 #endif // defined(USE_SYSTEM_ZLIB) |
3402 | 3098 |
3403 int compressed_size = compressed_max_size - compressor->avail_out; | 3099 int compressed_size = compressed_max_size - compressor->avail_out; |
3404 builder->Seek(compressed_size); | 3100 builder->Seek(compressed_size); |
3405 builder->RewriteLength(*this); | 3101 builder->RewriteLength(*this); |
3406 } | 3102 } |
3407 | 3103 |
3408 } // namespace net | 3104 } // namespace net |
OLD | NEW |