| 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 |