| 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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't | 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't |
| 6 // constantly adding and subtracting header sizes; this is ugly and error- | 6 // constantly adding and subtracting header sizes; this is ugly and error- |
| 7 // prone. | 7 // prone. |
| 8 | 8 |
| 9 #include "net/spdy/spdy_framer.h" | 9 #include "net/spdy/spdy_framer.h" |
| 10 | 10 |
| (...skipping 670 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 681 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 681 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
| 682 DCHECK(successful_read); | 682 DCHECK(successful_read); |
| 683 | 683 |
| 684 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); | 684 successful_read = reader->ReadUInt31(¤t_frame_stream_id_); |
| 685 DCHECK(successful_read); | 685 DCHECK(successful_read); |
| 686 | 686 |
| 687 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); | 687 remaining_data_length_ = current_frame_length_ - reader->GetBytesConsumed(); |
| 688 | 688 |
| 689 // Before we accept a DATA frame, we need to make sure we're not in the | 689 // Before we accept a DATA frame, we need to make sure we're not in the |
| 690 // middle of processing a header block. | 690 // middle of processing a header block. |
| 691 if (expect_continuation_ != 0 && control_frame_type_field != CONTINUATION) { | 691 const bool is_continuation_frame = (control_frame_type_field == |
| 692 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " | 692 SpdyConstants::SerializeFrameType(protocol_version(), CONTINUATION)); |
| 693 << "frame, but instead received frame type " | 693 if ((expect_continuation_ != 0) != is_continuation_frame) { |
| 694 << current_frame_type_; | 694 if (expect_continuation_ != 0) { |
| 695 set_error(SPDY_UNEXPECTED_FRAME); | 695 DLOG(ERROR) << "The framer was expecting to receive a CONTINUATION " |
| 696 return original_len - len; | 696 << "frame, but instead received frame type " |
| 697 } else if (control_frame_type_field == CONTINUATION && | 697 << control_frame_type_field; |
| 698 expect_continuation_ == 0) { | 698 } else { |
| 699 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; | 699 DLOG(ERROR) << "The framer received an unexpected CONTINUATION frame."; |
| 700 } |
| 700 set_error(SPDY_UNEXPECTED_FRAME); | 701 set_error(SPDY_UNEXPECTED_FRAME); |
| 701 return original_len - len; | 702 return original_len - len; |
| 702 } | 703 } |
| 703 } | 704 } |
| 704 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() | 705 DCHECK_EQ(is_control_frame ? GetControlFrameHeaderSize() |
| 705 : GetDataFrameMinimumSize(), | 706 : GetDataFrameMinimumSize(), |
| 706 reader->GetBytesConsumed()); | 707 reader->GetBytesConsumed()); |
| 707 DCHECK_EQ(current_frame_length_, | 708 DCHECK_EQ(current_frame_length_, |
| 708 remaining_data_length_ + reader->GetBytesConsumed()); | 709 remaining_data_length_ + reader->GetBytesConsumed()); |
| 709 | 710 |
| (...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 765 ProcessControlFrameHeader(control_frame_type_field); | 766 ProcessControlFrameHeader(control_frame_type_field); |
| 766 } | 767 } |
| 767 | 768 |
| 768 return original_len - len; | 769 return original_len - len; |
| 769 } | 770 } |
| 770 | 771 |
| 771 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 772 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
| 772 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 773 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
| 773 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 774 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
| 774 | 775 |
| 775 if (control_frame_type_field < FIRST_CONTROL_TYPE || | 776 // Early detection of deprecated frames that we ignore. |
| 776 control_frame_type_field > LAST_CONTROL_TYPE) { | 777 if (protocol_version() < SPDY4) { |
| 778 if (control_frame_type_field == NOOP) { |
| 779 current_frame_type_ = NOOP; |
| 780 DVLOG(1) << "NOOP control frame found. Ignoring."; |
| 781 CHANGE_STATE(SPDY_AUTO_RESET); |
| 782 return; |
| 783 } |
| 784 |
| 785 if (control_frame_type_field == CREDENTIAL) { |
| 786 current_frame_type_ = CREDENTIAL; |
| 787 DCHECK_EQ(3, protocol_version()); |
| 788 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
| 789 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 790 return; |
| 791 } |
| 792 } |
| 793 |
| 794 if (!SpdyConstants::IsValidFrameType(protocol_version(), |
| 795 control_frame_type_field)) { |
| 796 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
| 797 << " (protocol version: " << protocol_version() << ")"; |
| 777 set_error(SPDY_INVALID_CONTROL_FRAME); | 798 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 778 return; | 799 return; |
| 779 } | 800 } |
| 780 | 801 |
| 781 current_frame_type_ = static_cast<SpdyFrameType>(control_frame_type_field); | 802 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
| 782 | 803 control_frame_type_field); |
| 783 if (current_frame_type_ == NOOP) { | |
| 784 DVLOG(1) << "NOOP control frame found. Ignoring."; | |
| 785 CHANGE_STATE(SPDY_AUTO_RESET); | |
| 786 return; | |
| 787 } | |
| 788 | |
| 789 if (current_frame_type_ == CREDENTIAL) { | |
| 790 DCHECK_EQ(3, protocol_version()); | |
| 791 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | |
| 792 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | |
| 793 return; | |
| 794 } | |
| 795 | 804 |
| 796 // Do some sanity checking on the control frame sizes and flags. | 805 // Do some sanity checking on the control frame sizes and flags. |
| 797 switch (current_frame_type_) { | 806 switch (current_frame_type_) { |
| 798 case SYN_STREAM: | 807 case SYN_STREAM: |
| 799 DCHECK_GT(4, spdy_version_); | |
| 800 if (current_frame_length_ < GetSynStreamMinimumSize()) { | 808 if (current_frame_length_ < GetSynStreamMinimumSize()) { |
| 801 set_error(SPDY_INVALID_CONTROL_FRAME); | 809 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 802 } else if (current_frame_flags_ & | 810 } else if (current_frame_flags_ & |
| 803 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { | 811 ~(CONTROL_FLAG_FIN | CONTROL_FLAG_UNIDIRECTIONAL)) { |
| 804 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 812 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 805 } | 813 } |
| 806 break; | 814 break; |
| 807 case SYN_REPLY: | 815 case SYN_REPLY: |
| 808 if (current_frame_length_ < GetSynReplyMinimumSize()) { | 816 if (current_frame_length_ < GetSynReplyMinimumSize()) { |
| 809 set_error(SPDY_INVALID_CONTROL_FRAME); | 817 set_error(SPDY_INVALID_CONTROL_FRAME); |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 912 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 920 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
| 913 set_error(SPDY_INVALID_CONTROL_FRAME); | 921 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 914 } else if (spdy_version_ < 4 && current_frame_flags_ != 0) { | 922 } else if (spdy_version_ < 4 && current_frame_flags_ != 0) { |
| 915 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 916 } else if (spdy_version_ >= 4 && current_frame_flags_ & | 924 } else if (spdy_version_ >= 4 && current_frame_flags_ & |
| 917 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { | 925 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { |
| 918 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 919 } | 927 } |
| 920 break; | 928 break; |
| 921 case CONTINUATION: | 929 case CONTINUATION: |
| 922 if (current_frame_length_ < GetContinuationMinimumSize() || | 930 if (current_frame_length_ < GetContinuationMinimumSize()) { |
| 923 protocol_version() < 4) { | |
| 924 set_error(SPDY_INVALID_CONTROL_FRAME); | 931 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 925 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { | 932 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
| 926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 927 } | 934 } |
| 928 break; | 935 break; |
| 929 default: | 936 default: |
| 930 LOG(WARNING) << "Valid " << display_protocol_ | 937 LOG(WARNING) << "Valid " << display_protocol_ |
| 931 << " control frame with unhandled type: " | 938 << " control frame with unhandled type: " |
| 932 << current_frame_type_; | 939 << current_frame_type_; |
| 933 // This branch should be unreachable because of the frame type bounds | 940 // This branch should be unreachable because of the frame type bounds |
| (...skipping 1901 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2835 builder->Seek(compressed_size); | 2842 builder->Seek(compressed_size); |
| 2836 builder->RewriteLength(*this); | 2843 builder->RewriteLength(*this); |
| 2837 | 2844 |
| 2838 pre_compress_bytes.Add(uncompressed_len); | 2845 pre_compress_bytes.Add(uncompressed_len); |
| 2839 post_compress_bytes.Add(compressed_size); | 2846 post_compress_bytes.Add(compressed_size); |
| 2840 | 2847 |
| 2841 compressed_frames.Increment(); | 2848 compressed_frames.Increment(); |
| 2842 } | 2849 } |
| 2843 | 2850 |
| 2844 } // namespace net | 2851 } // namespace net |
| OLD | NEW |