| 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 "base/lazy_instance.h" | 7 #include "base/lazy_instance.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/metrics/stats_counters.h" | 9 #include "base/metrics/stats_counters.h" |
| 10 #include "base/third_party/valgrind/memcheck.h" | 10 #include "base/third_party/valgrind/memcheck.h" |
| (...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 159 remaining_data_length_ = 0; | 159 remaining_data_length_ = 0; |
| 160 remaining_control_header_ = 0; | 160 remaining_control_header_ = 0; |
| 161 current_frame_buffer_length_ = 0; | 161 current_frame_buffer_length_ = 0; |
| 162 current_frame_type_ = DATA; | 162 current_frame_type_ = DATA; |
| 163 current_frame_flags_ = 0; | 163 current_frame_flags_ = 0; |
| 164 current_frame_length_ = 0; | 164 current_frame_length_ = 0; |
| 165 current_frame_stream_id_ = kInvalidStream; | 165 current_frame_stream_id_ = kInvalidStream; |
| 166 settings_scratch_.Reset(); | 166 settings_scratch_.Reset(); |
| 167 altsvc_scratch_.Reset(); | 167 altsvc_scratch_.Reset(); |
| 168 remaining_padding_payload_length_ = 0; | 168 remaining_padding_payload_length_ = 0; |
| 169 remaining_padding_length_fields_ = 0; | |
| 170 } | 169 } |
| 171 | 170 |
| 172 size_t SpdyFramer::GetDataFrameMinimumSize() const { | 171 size_t SpdyFramer::GetDataFrameMinimumSize() const { |
| 173 return SpdyConstants::GetDataFrameMinimumSize(); | 172 return SpdyConstants::GetDataFrameMinimumSize(); |
| 174 } | 173 } |
| 175 | 174 |
| 176 // Size, in bytes, of the control frame header. | 175 // Size, in bytes, of the control frame header. |
| 177 size_t SpdyFramer::GetControlFrameHeaderSize() const { | 176 size_t SpdyFramer::GetControlFrameHeaderSize() const { |
| 178 return SpdyConstants::GetControlFrameHeaderSize(protocol_version()); | 177 return SpdyConstants::GetControlFrameHeaderSize(protocol_version()); |
| 179 } | 178 } |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 case DATA: | 461 case DATA: |
| 463 return "DATA"; | 462 return "DATA"; |
| 464 case SYN_STREAM: | 463 case SYN_STREAM: |
| 465 return "SYN_STREAM"; | 464 return "SYN_STREAM"; |
| 466 case SYN_REPLY: | 465 case SYN_REPLY: |
| 467 return "SYN_REPLY"; | 466 return "SYN_REPLY"; |
| 468 case RST_STREAM: | 467 case RST_STREAM: |
| 469 return "RST_STREAM"; | 468 return "RST_STREAM"; |
| 470 case SETTINGS: | 469 case SETTINGS: |
| 471 return "SETTINGS"; | 470 return "SETTINGS"; |
| 472 case NOOP: | |
| 473 return "NOOP"; | |
| 474 case PING: | 471 case PING: |
| 475 return "PING"; | 472 return "PING"; |
| 476 case GOAWAY: | 473 case GOAWAY: |
| 477 return "GOAWAY"; | 474 return "GOAWAY"; |
| 478 case HEADERS: | 475 case HEADERS: |
| 479 return "HEADERS"; | 476 return "HEADERS"; |
| 480 case WINDOW_UPDATE: | 477 case WINDOW_UPDATE: |
| 481 return "WINDOW_UPDATE"; | 478 return "WINDOW_UPDATE"; |
| 482 case CREDENTIAL: | 479 case CREDENTIAL: |
| 483 return "CREDENTIAL"; | 480 return "CREDENTIAL"; |
| (...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 654 | 651 |
| 655 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader | 652 // Using a scoped_ptr here since we may need to create a new SpdyFrameReader |
| 656 // when processing DATA frames below. | 653 // when processing DATA frames below. |
| 657 scoped_ptr<SpdyFrameReader> reader( | 654 scoped_ptr<SpdyFrameReader> reader( |
| 658 new SpdyFrameReader(current_frame_buffer_.get(), | 655 new SpdyFrameReader(current_frame_buffer_.get(), |
| 659 current_frame_buffer_length_)); | 656 current_frame_buffer_length_)); |
| 660 | 657 |
| 661 uint16 version = 0; | 658 uint16 version = 0; |
| 662 bool is_control_frame = false; | 659 bool is_control_frame = false; |
| 663 | 660 |
| 664 uint16 control_frame_type_field = DATA; | 661 uint16 control_frame_type_field = |
| 662 SpdyConstants::DataFrameType(protocol_version()); |
| 665 // ProcessControlFrameHeader() will set current_frame_type_ to the | 663 // ProcessControlFrameHeader() will set current_frame_type_ to the |
| 666 // correct value if this is a valid control frame. | 664 // correct value if this is a valid control frame. |
| 667 current_frame_type_ = DATA; | 665 current_frame_type_ = DATA; |
| 668 if (protocol_version() <= SPDY3) { | 666 if (protocol_version() <= SPDY3) { |
| 669 bool successful_read = reader->ReadUInt16(&version); | 667 bool successful_read = reader->ReadUInt16(&version); |
| 670 DCHECK(successful_read); | 668 DCHECK(successful_read); |
| 671 is_control_frame = (version & kControlFlagMask) != 0; | 669 is_control_frame = (version & kControlFlagMask) != 0; |
| 672 version &= ~kControlFlagMask; // Only valid for control frames. | 670 version &= ~kControlFlagMask; // Only valid for control frames. |
| 673 if (is_control_frame) { | 671 if (is_control_frame) { |
| 674 // We check version before we check validity: version can never be | 672 // We check version before we check validity: version can never be |
| (...skipping 27 matching lines...) Expand all Loading... |
| 702 successful_read = reader->ReadUInt24(&length_field); | 700 successful_read = reader->ReadUInt24(&length_field); |
| 703 DCHECK(successful_read); | 701 DCHECK(successful_read); |
| 704 remaining_data_length_ = length_field; | 702 remaining_data_length_ = length_field; |
| 705 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); | 703 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); |
| 706 } else { | 704 } else { |
| 707 version = protocol_version(); | 705 version = protocol_version(); |
| 708 uint16 length_field = 0; | 706 uint16 length_field = 0; |
| 709 bool successful_read = reader->ReadUInt16(&length_field); | 707 bool successful_read = reader->ReadUInt16(&length_field); |
| 710 DCHECK(successful_read); | 708 DCHECK(successful_read); |
| 711 | 709 |
| 712 uint8 control_frame_type_field_uint8 = DATA; | 710 uint8 control_frame_type_field_uint8 = |
| 711 SpdyConstants::DataFrameType(protocol_version()); |
| 713 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); | 712 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); |
| 714 DCHECK(successful_read); | 713 DCHECK(successful_read); |
| 715 // We check control_frame_type_field's validity in | 714 // We check control_frame_type_field's validity in |
| 716 // ProcessControlFrameHeader(). | 715 // ProcessControlFrameHeader(). |
| 717 control_frame_type_field = control_frame_type_field_uint8; | 716 control_frame_type_field = control_frame_type_field_uint8; |
| 718 is_control_frame = (control_frame_type_field != DATA); | 717 is_control_frame = (protocol_version() > SPDY3) ? |
| 718 control_frame_type_field != |
| 719 SpdyConstants::SerializeFrameType(protocol_version(), DATA) : |
| 720 control_frame_type_field != 0; |
| 719 | 721 |
| 720 if (is_control_frame) { | 722 if (is_control_frame) { |
| 721 current_frame_length_ = length_field + GetControlFrameHeaderSize(); | 723 current_frame_length_ = length_field + GetControlFrameHeaderSize(); |
| 722 } else { | 724 } else { |
| 723 current_frame_length_ = length_field + GetDataFrameMinimumSize(); | 725 current_frame_length_ = length_field + GetDataFrameMinimumSize(); |
| 724 } | 726 } |
| 725 | 727 |
| 726 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 728 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
| 727 DCHECK(successful_read); | 729 DCHECK(successful_read); |
| 728 | 730 |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 771 // if we're here, then we have the common header all received. | 773 // if we're here, then we have the common header all received. |
| 772 if (!is_control_frame) { | 774 if (!is_control_frame) { |
| 773 if (protocol_version() > SPDY3) { | 775 if (protocol_version() > SPDY3) { |
| 774 // Catch bogus tests sending oversized DATA frames. | 776 // Catch bogus tests sending oversized DATA frames. |
| 775 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) | 777 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) |
| 776 << "DATA frame too large for SPDY >= 4."; | 778 << "DATA frame too large for SPDY >= 4."; |
| 777 } | 779 } |
| 778 | 780 |
| 779 uint8 valid_data_flags = 0; | 781 uint8 valid_data_flags = 0; |
| 780 if (protocol_version() > SPDY3) { | 782 if (protocol_version() > SPDY3) { |
| 781 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | | 783 valid_data_flags = |
| 782 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; | 784 DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | DATA_FLAG_PADDED; |
| 783 } else { | 785 } else { |
| 784 valid_data_flags = DATA_FLAG_FIN; | 786 valid_data_flags = DATA_FLAG_FIN; |
| 785 } | 787 } |
| 786 | 788 |
| 787 if (current_frame_flags_ & ~valid_data_flags) { | 789 if (current_frame_flags_ & ~valid_data_flags) { |
| 788 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 790 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| 789 } else { | 791 } else { |
| 790 visitor_->OnDataFrameHeader(current_frame_stream_id_, | 792 visitor_->OnDataFrameHeader(current_frame_stream_id_, |
| 791 remaining_data_length_, | 793 remaining_data_length_, |
| 792 current_frame_flags_ & DATA_FLAG_FIN); | 794 current_frame_flags_ & DATA_FLAG_FIN); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 805 ProcessControlFrameHeader(control_frame_type_field); | 807 ProcessControlFrameHeader(control_frame_type_field); |
| 806 } | 808 } |
| 807 | 809 |
| 808 return original_len - len; | 810 return original_len - len; |
| 809 } | 811 } |
| 810 | 812 |
| 811 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 813 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
| 812 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 814 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
| 813 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 815 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
| 814 | 816 |
| 817 // TODO(mlavan): Either remove credential frames from the code entirely, |
| 818 // or add them to parsing + serialization methods for SPDY3. |
| 815 // Early detection of deprecated frames that we ignore. | 819 // Early detection of deprecated frames that we ignore. |
| 816 if (protocol_version() <= SPDY3) { | 820 if (protocol_version() <= SPDY3) { |
| 817 if (control_frame_type_field == NOOP) { | |
| 818 current_frame_type_ = NOOP; | |
| 819 DVLOG(1) << "NOOP control frame found. Ignoring."; | |
| 820 CHANGE_STATE(SPDY_AUTO_RESET); | |
| 821 return; | |
| 822 } | |
| 823 | 821 |
| 824 if (control_frame_type_field == CREDENTIAL) { | 822 if (control_frame_type_field == CREDENTIAL) { |
| 825 current_frame_type_ = CREDENTIAL; | 823 current_frame_type_ = CREDENTIAL; |
| 826 DCHECK_EQ(SPDY3, protocol_version()); | 824 DCHECK_EQ(SPDY3, protocol_version()); |
| 827 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | 825 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
| 828 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 826 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 829 return; | 827 return; |
| 830 } | 828 } |
| 831 } | 829 } |
| 832 | 830 |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 870 } else if (current_frame_flags_ != 0) { | 868 } else if (current_frame_flags_ != 0) { |
| 871 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 869 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 872 } | 870 } |
| 873 break; | 871 break; |
| 874 case SETTINGS: | 872 case SETTINGS: |
| 875 { | 873 { |
| 876 // Make sure that we have an integral number of 8-byte key/value pairs, | 874 // Make sure that we have an integral number of 8-byte key/value pairs, |
| 877 // plus a 4-byte length field in SPDY3 and below. | 875 // plus a 4-byte length field in SPDY3 and below. |
| 878 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0); | 876 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0); |
| 879 // Size of each key/value pair in bytes. | 877 // Size of each key/value pair in bytes. |
| 880 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); | 878 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version()); |
| 881 if (current_frame_length_ < GetSettingsMinimumSize() || | 879 if (current_frame_length_ < GetSettingsMinimumSize() || |
| 882 (current_frame_length_ - GetControlFrameHeaderSize()) | 880 (current_frame_length_ - GetControlFrameHeaderSize()) |
| 883 % setting_size != values_prefix_size) { | 881 % setting_size != values_prefix_size) { |
| 884 DLOG(WARNING) << "Invalid length for SETTINGS frame: " | 882 DLOG(WARNING) << "Invalid length for SETTINGS frame: " |
| 885 << current_frame_length_; | 883 << current_frame_length_; |
| 886 set_error(SPDY_INVALID_CONTROL_FRAME); | 884 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 887 } else if (protocol_version() <= SPDY3 && | 885 } else if (protocol_version() <= SPDY3 && |
| 888 current_frame_flags_ & | 886 current_frame_flags_ & |
| 889 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { | 887 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { |
| 890 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 888 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 931 } | 929 } |
| 932 if (current_frame_length_ < min_size) { | 930 if (current_frame_length_ < min_size) { |
| 933 set_error(SPDY_INVALID_CONTROL_FRAME); | 931 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 934 } else if (protocol_version() <= SPDY3 && | 932 } else if (protocol_version() <= SPDY3 && |
| 935 current_frame_flags_ & ~CONTROL_FLAG_FIN) { | 933 current_frame_flags_ & ~CONTROL_FLAG_FIN) { |
| 936 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 934 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 937 } else if (protocol_version() > SPDY3 && | 935 } else if (protocol_version() > SPDY3 && |
| 938 current_frame_flags_ & | 936 current_frame_flags_ & |
| 939 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 937 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
| 940 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | | 938 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | |
| 941 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) { | 939 HEADERS_FLAG_PADDED)) { |
| 942 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 940 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 943 } | 941 } |
| 944 } | 942 } |
| 945 break; | 943 break; |
| 946 case WINDOW_UPDATE: | 944 case WINDOW_UPDATE: |
| 947 if (current_frame_length_ != GetWindowUpdateSize()) { | 945 if (current_frame_length_ != GetWindowUpdateSize()) { |
| 948 set_error(SPDY_INVALID_CONTROL_FRAME); | 946 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 949 } else if (current_frame_flags_ != 0) { | 947 } else if (current_frame_flags_ != 0) { |
| 950 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 948 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 951 } | 949 } |
| 952 break; | 950 break; |
| 953 case BLOCKED: | 951 case BLOCKED: |
| 954 if (current_frame_length_ != GetBlockedSize() || | 952 if (current_frame_length_ != GetBlockedSize() || |
| 955 protocol_version() <= SPDY3) { | 953 protocol_version() <= SPDY3) { |
| 956 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. | 954 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. |
| 957 set_error(SPDY_INVALID_CONTROL_FRAME); | 955 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 958 } else if (current_frame_flags_ != 0) { | 956 } else if (current_frame_flags_ != 0) { |
| 959 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 957 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 960 } | 958 } |
| 961 break; | 959 break; |
| 962 case PUSH_PROMISE: | 960 case PUSH_PROMISE: |
| 963 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 961 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
| 964 set_error(SPDY_INVALID_CONTROL_FRAME); | 962 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 965 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 963 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
| 966 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 964 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 967 } else if (protocol_version() > SPDY3 && | 965 } else if (protocol_version() > SPDY3 && |
| 968 current_frame_flags_ & | 966 current_frame_flags_ & |
| 969 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | | 967 ~(PUSH_PROMISE_FLAG_END_PUSH_PROMISE | |
| 970 HEADERS_FLAG_PAD_LOW | HEADERS_FLAG_PAD_HIGH)) { | 968 HEADERS_FLAG_PADDED)) { |
| 971 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 969 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 972 } | 970 } |
| 973 break; | 971 break; |
| 974 case CONTINUATION: | 972 case CONTINUATION: |
| 975 if (current_frame_length_ < GetContinuationMinimumSize() || | 973 if (current_frame_length_ < GetContinuationMinimumSize() || |
| 976 protocol_version() <= SPDY3) { | 974 protocol_version() <= SPDY3) { |
| 977 set_error(SPDY_INVALID_CONTROL_FRAME); | 975 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 978 } else if (current_frame_flags_ & | 976 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { |
| 979 ~(HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_PAD_LOW | | |
| 980 HEADERS_FLAG_PAD_HIGH)) { | |
| 981 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 977 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 982 } | 978 } |
| 983 break; | 979 break; |
| 984 case ALTSVC: | 980 case ALTSVC: |
| 985 if (current_frame_length_ <= GetAltSvcMinimumSize()) { | 981 if (current_frame_length_ <= GetAltSvcMinimumSize()) { |
| 986 set_error(SPDY_INVALID_CONTROL_FRAME); | 982 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 987 } else if (current_frame_flags_ != 0) { | 983 } else if (current_frame_flags_ != 0) { |
| 988 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 984 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 989 } | 985 } |
| 990 break; | 986 break; |
| (...skipping 521 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1512 if (debug_visitor_) { | 1508 if (debug_visitor_) { |
| 1513 debug_visitor_->OnReceiveCompressedFrame( | 1509 debug_visitor_->OnReceiveCompressedFrame( |
| 1514 current_frame_stream_id_, | 1510 current_frame_stream_id_, |
| 1515 current_frame_type_, | 1511 current_frame_type_, |
| 1516 current_frame_length_); | 1512 current_frame_length_); |
| 1517 } | 1513 } |
| 1518 visitor_->OnContinuation(current_frame_stream_id_, | 1514 visitor_->OnContinuation(current_frame_stream_id_, |
| 1519 (current_frame_flags_ & | 1515 (current_frame_flags_ & |
| 1520 HEADERS_FLAG_END_HEADERS) != 0); | 1516 HEADERS_FLAG_END_HEADERS) != 0); |
| 1521 } | 1517 } |
| 1522 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); | 1518 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
| 1523 break; | 1519 break; |
| 1524 default: | 1520 default: |
| 1525 DCHECK(false); | 1521 DCHECK(false); |
| 1526 } | 1522 } |
| 1527 } | 1523 } |
| 1528 return original_len - len; | 1524 return original_len - len; |
| 1529 } | 1525 } |
| 1530 | 1526 |
| 1531 // Does not buffer the control payload. Instead, either passes directly to the | 1527 // Does not buffer the control payload. Instead, either passes directly to the |
| 1532 // visitor or decompresses and then passes directly to the visitor, via | 1528 // visitor or decompresses and then passes directly to the visitor, via |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1602 return process_bytes; | 1598 return process_bytes; |
| 1603 } | 1599 } |
| 1604 | 1600 |
| 1605 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, | 1601 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, |
| 1606 size_t data_len) { | 1602 size_t data_len) { |
| 1607 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); | 1603 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); |
| 1608 DCHECK_EQ(SETTINGS, current_frame_type_); | 1604 DCHECK_EQ(SETTINGS, current_frame_type_); |
| 1609 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); | 1605 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); |
| 1610 size_t processed_bytes = 0; | 1606 size_t processed_bytes = 0; |
| 1611 | 1607 |
| 1612 size_t setting_size = protocol_version() <= SPDY3 ? 8 : 5; | 1608 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version()); |
| 1613 | 1609 |
| 1614 // Loop over our incoming data. | 1610 // Loop over our incoming data. |
| 1615 while (unprocessed_bytes > 0) { | 1611 while (unprocessed_bytes > 0) { |
| 1616 // Process up to one setting at a time. | 1612 // Process up to one setting at a time. |
| 1617 size_t processing = std::min( | 1613 size_t processing = std::min( |
| 1618 unprocessed_bytes, | 1614 unprocessed_bytes, |
| 1619 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len)); | 1615 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len)); |
| 1620 | 1616 |
| 1621 // Check if we have a complete setting in our input. | 1617 // Check if we have a complete setting in our input. |
| 1622 if (processing == setting_size) { | 1618 if (processing == setting_size) { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1696 // Extract fields. | 1692 // Extract fields. |
| 1697 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. | 1693 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. |
| 1698 if (protocol_version() <= SPDY3) { | 1694 if (protocol_version() <= SPDY3) { |
| 1699 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); | 1695 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); |
| 1700 SettingsFlagsAndId id_and_flags = | 1696 SettingsFlagsAndId id_and_flags = |
| 1701 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire); | 1697 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire); |
| 1702 id_field = id_and_flags.id(); | 1698 id_field = id_and_flags.id(); |
| 1703 flags = id_and_flags.flags(); | 1699 flags = id_and_flags.flags(); |
| 1704 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1700 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
| 1705 } else { | 1701 } else { |
| 1706 id_field = *(reinterpret_cast<const uint8*>(data)); | 1702 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); |
| 1707 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); | 1703 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); |
| 1708 } | 1704 } |
| 1709 | 1705 |
| 1710 // Validate id. | 1706 // Validate id. |
| 1711 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { | 1707 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
| 1712 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1708 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
| 1713 return false; | 1709 return false; |
| 1714 } | 1710 } |
| 1715 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); | 1711 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); |
| 1716 | 1712 |
| 1717 if (protocol_version() <= SPDY3) { | 1713 if (protocol_version() <= SPDY3) { |
| (...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1783 } | 1779 } |
| 1784 break; | 1780 break; |
| 1785 case BLOCKED: { | 1781 case BLOCKED: { |
| 1786 DCHECK_LT(SPDY3, protocol_version()); | 1782 DCHECK_LT(SPDY3, protocol_version()); |
| 1787 DCHECK(reader.IsDoneReading()); | 1783 DCHECK(reader.IsDoneReading()); |
| 1788 visitor_->OnBlocked(current_frame_stream_id_); | 1784 visitor_->OnBlocked(current_frame_stream_id_); |
| 1789 } | 1785 } |
| 1790 break; | 1786 break; |
| 1791 case PRIORITY: { | 1787 case PRIORITY: { |
| 1792 DCHECK_LT(SPDY3, protocol_version()); | 1788 DCHECK_LT(SPDY3, protocol_version()); |
| 1793 // TODO(hkhalil): Process PRIORITY frames rather than ignore them. | 1789 uint32 parent_stream_id; |
| 1794 reader.Seek(5); | 1790 uint8 weight; |
| 1791 bool exclusive; |
| 1792 bool successful_read = true; |
| 1793 successful_read = reader.ReadUInt32(&parent_stream_id); |
| 1794 DCHECK(successful_read); |
| 1795 // Exclusivity is indicated by a single bit flag. |
| 1796 exclusive = (parent_stream_id >> 31) != 0; |
| 1797 // Zero out the highest-order bit to get the parent stream id. |
| 1798 parent_stream_id &= 0x7fffffff; |
| 1799 successful_read = reader.ReadUInt8(&weight); |
| 1800 DCHECK(successful_read); |
| 1795 DCHECK(reader.IsDoneReading()); | 1801 DCHECK(reader.IsDoneReading()); |
| 1802 visitor_->OnPriority( |
| 1803 current_frame_stream_id_, parent_stream_id, weight, exclusive); |
| 1796 } | 1804 } |
| 1797 break; | 1805 break; |
| 1798 default: | 1806 default: |
| 1799 // Unreachable. | 1807 // Unreachable. |
| 1800 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; | 1808 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; |
| 1801 } | 1809 } |
| 1802 | 1810 |
| 1803 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 1811 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 1804 } | 1812 } |
| 1805 return original_len - len; | 1813 return original_len - len; |
| (...skipping 255 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2061 StringPiece(altsvc_scratch_.host.get(), | 2069 StringPiece(altsvc_scratch_.host.get(), |
| 2062 altsvc_scratch_.host_len), | 2070 altsvc_scratch_.host_len), |
| 2063 StringPiece(altsvc_scratch_.origin.get(), | 2071 StringPiece(altsvc_scratch_.origin.get(), |
| 2064 altsvc_scratch_.origin_len)); | 2072 altsvc_scratch_.origin_len)); |
| 2065 CHANGE_STATE(SPDY_AUTO_RESET); | 2073 CHANGE_STATE(SPDY_AUTO_RESET); |
| 2066 } | 2074 } |
| 2067 | 2075 |
| 2068 return processed_bytes; | 2076 return processed_bytes; |
| 2069 } | 2077 } |
| 2070 | 2078 |
| 2079 // TODO(raullenchai): ProcessFramePaddingLength should be able to deal with |
| 2080 // HEADERS_FLAG_PADDED and PUSH_PROMISE_FLAG_PADDED as well (see b/15777051). |
| 2071 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { | 2081 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { |
| 2072 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); | 2082 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); |
| 2083 DCHECK_EQ(remaining_padding_payload_length_, 0u); |
| 2073 | 2084 |
| 2074 size_t original_len = len; | 2085 size_t original_len = len; |
| 2075 if (remaining_padding_length_fields_ == 0) { | 2086 if (current_frame_flags_ & DATA_FLAG_PADDED) { |
| 2076 DCHECK_EQ(remaining_padding_payload_length_, 0u); | 2087 if (len != 0) { |
| 2077 bool pad_low = false; | 2088 if (remaining_data_length_ < 1) { |
| 2078 bool pad_high = false; | 2089 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| 2079 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) { | 2090 return 0; |
| 2080 pad_low = true; | 2091 } |
| 2081 ++remaining_padding_length_fields_; | 2092 |
| 2082 } | 2093 remaining_padding_payload_length_ = *reinterpret_cast<const uint8*>(data); |
| 2083 if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) { | 2094 ++data; |
| 2084 pad_high = true; | 2095 --len; |
| 2085 ++remaining_padding_length_fields_; | 2096 --remaining_data_length_; |
| 2086 } | 2097 } else { |
| 2087 if ((pad_high && !pad_low) || | 2098 // We don't have the data available for parsing the pad length field. Keep |
| 2088 remaining_data_length_ < remaining_padding_length_fields_) { | 2099 // waiting. |
| 2089 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | |
| 2090 return 0; | 2100 return 0; |
| 2091 } | 2101 } |
| 2092 } | 2102 } |
| 2093 | 2103 |
| 2094 // Parse the padding length. | 2104 if (remaining_padding_payload_length_ > remaining_data_length_) { |
| 2095 while (len != 0 && remaining_padding_length_fields_ != 0) { | 2105 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); |
| 2096 remaining_padding_payload_length_ = | 2106 return 0; |
| 2097 (remaining_padding_payload_length_ << 8) + | |
| 2098 *reinterpret_cast<const uint8*>(data); | |
| 2099 ++data; | |
| 2100 --len; | |
| 2101 --remaining_padding_length_fields_; | |
| 2102 --remaining_data_length_; | |
| 2103 } | 2107 } |
| 2104 | 2108 if (current_frame_type_ == DATA) { |
| 2105 if (remaining_padding_length_fields_ == 0) { | 2109 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); |
| 2106 if (remaining_padding_payload_length_ > remaining_data_length_) { | 2110 } else { |
| 2107 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); | 2111 DCHECK(current_frame_type_ == HEADERS || |
| 2108 return 0; | 2112 current_frame_type_ == PUSH_PROMISE || |
| 2109 } | 2113 current_frame_type_ == SYN_STREAM || |
| 2110 if (current_frame_type_ == DATA) { | 2114 current_frame_type_ == SYN_REPLY) |
| 2111 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); | 2115 << current_frame_type_; |
| 2112 } else { | 2116 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); |
| 2113 DCHECK(current_frame_type_ == HEADERS || | |
| 2114 current_frame_type_ == PUSH_PROMISE || | |
| 2115 current_frame_type_ == CONTINUATION || | |
| 2116 current_frame_type_ == SYN_STREAM || | |
| 2117 current_frame_type_ == SYN_REPLY) | |
| 2118 << current_frame_type_; | |
| 2119 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); | |
| 2120 } | |
| 2121 } | 2117 } |
| 2122 return original_len - len; | 2118 return original_len - len; |
| 2123 } | 2119 } |
| 2124 | 2120 |
| 2125 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { | 2121 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) { |
| 2126 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); | 2122 DCHECK_EQ(SPDY_CONSUME_PADDING, state_); |
| 2127 | 2123 |
| 2128 size_t original_len = len; | 2124 size_t original_len = len; |
| 2129 if (remaining_padding_payload_length_ > 0) { | 2125 if (remaining_padding_payload_length_ > 0) { |
| 2130 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); | 2126 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_); |
| (...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2252 | 2248 |
| 2253 SpdySerializedFrame* SpdyFramer::SerializeData( | 2249 SpdySerializedFrame* SpdyFramer::SerializeData( |
| 2254 const SpdyDataIR& data_ir) const { | 2250 const SpdyDataIR& data_ir) const { |
| 2255 uint8 flags = DATA_FLAG_NONE; | 2251 uint8 flags = DATA_FLAG_NONE; |
| 2256 if (data_ir.fin()) { | 2252 if (data_ir.fin()) { |
| 2257 flags = DATA_FLAG_FIN; | 2253 flags = DATA_FLAG_FIN; |
| 2258 } | 2254 } |
| 2259 | 2255 |
| 2260 if (protocol_version() > SPDY3) { | 2256 if (protocol_version() > SPDY3) { |
| 2261 int num_padding_fields = 0; | 2257 int num_padding_fields = 0; |
| 2262 if (data_ir.pad_low()) { | 2258 if (data_ir.padded()) { |
| 2263 flags |= DATA_FLAG_PAD_LOW; | 2259 flags |= DATA_FLAG_PADDED; |
| 2264 ++num_padding_fields; | |
| 2265 } | |
| 2266 if (data_ir.pad_high()) { | |
| 2267 flags |= DATA_FLAG_PAD_HIGH; | |
| 2268 ++num_padding_fields; | 2260 ++num_padding_fields; |
| 2269 } | 2261 } |
| 2270 | 2262 |
| 2271 const size_t size_with_padding = num_padding_fields + | 2263 const size_t size_with_padding = num_padding_fields + |
| 2272 data_ir.data().length() + data_ir.padding_payload_len() + | 2264 data_ir.data().length() + data_ir.padding_payload_len() + |
| 2273 GetDataFrameMinimumSize(); | 2265 GetDataFrameMinimumSize(); |
| 2274 SpdyFrameBuilder builder(size_with_padding, protocol_version()); | 2266 SpdyFrameBuilder builder(size_with_padding, protocol_version()); |
| 2275 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2267 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
| 2276 if (data_ir.pad_high()) { | 2268 if (data_ir.padded()) { |
| 2277 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | |
| 2278 } | |
| 2279 if (data_ir.pad_low()) { | |
| 2280 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2269 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 2281 } | 2270 } |
| 2282 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); | 2271 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); |
| 2283 if (data_ir.padding_payload_len() > 0) { | 2272 if (data_ir.padding_payload_len() > 0) { |
| 2284 string padding = string(data_ir.padding_payload_len(), '0'); | 2273 string padding = string(data_ir.padding_payload_len(), '0'); |
| 2285 builder.WriteBytes(padding.data(), padding.length()); | 2274 builder.WriteBytes(padding.data(), padding.length()); |
| 2286 } | 2275 } |
| 2287 DCHECK_EQ(size_with_padding, builder.length()); | 2276 DCHECK_EQ(size_with_padding, builder.length()); |
| 2288 return builder.take(); | 2277 return builder.take(); |
| 2289 } else { | 2278 } else { |
| 2290 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length(); | 2279 const size_t size = GetDataFrameMinimumSize() + data_ir.data().length(); |
| 2291 SpdyFrameBuilder builder(size, protocol_version()); | 2280 SpdyFrameBuilder builder(size, protocol_version()); |
| 2292 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2281 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
| 2293 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); | 2282 builder.WriteBytes(data_ir.data().data(), data_ir.data().length()); |
| 2294 DCHECK_EQ(size, builder.length()); | 2283 DCHECK_EQ(size, builder.length()); |
| 2295 return builder.take(); | 2284 return builder.take(); |
| 2296 } | 2285 } |
| 2297 } | 2286 } |
| 2298 | 2287 |
| 2299 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 2288 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( |
| 2300 const SpdyDataIR& data_ir) const { | 2289 const SpdyDataIR& data_ir) const { |
| 2301 uint8 flags = DATA_FLAG_NONE; | 2290 uint8 flags = DATA_FLAG_NONE; |
| 2302 if (data_ir.fin()) { | 2291 if (data_ir.fin()) { |
| 2303 flags = DATA_FLAG_FIN; | 2292 flags = DATA_FLAG_FIN; |
| 2304 } | 2293 } |
| 2305 | 2294 |
| 2306 size_t frame_size = GetDataFrameMinimumSize(); | 2295 size_t frame_size = GetDataFrameMinimumSize(); |
| 2307 size_t num_padding_fields = 0; | 2296 size_t num_padding_fields = 0; |
| 2308 if (protocol_version() > SPDY3) { | 2297 if (protocol_version() > SPDY3) { |
| 2309 if (data_ir.pad_low()) { | 2298 if (data_ir.padded()) { |
| 2310 flags |= DATA_FLAG_PAD_LOW; | 2299 flags |= DATA_FLAG_PADDED; |
| 2311 ++num_padding_fields; | |
| 2312 } | |
| 2313 if (data_ir.pad_high()) { | |
| 2314 flags |= DATA_FLAG_PAD_HIGH; | |
| 2315 ++num_padding_fields; | 2300 ++num_padding_fields; |
| 2316 } | 2301 } |
| 2317 frame_size += num_padding_fields; | 2302 frame_size += num_padding_fields; |
| 2318 } | 2303 } |
| 2319 | 2304 |
| 2320 SpdyFrameBuilder builder(frame_size, protocol_version()); | 2305 SpdyFrameBuilder builder(frame_size, protocol_version()); |
| 2321 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); | 2306 builder.WriteDataFrameHeader(*this, data_ir.stream_id(), flags); |
| 2322 if (protocol_version() > SPDY3) { | 2307 if (protocol_version() > SPDY3) { |
| 2323 if (data_ir.pad_high()) { | 2308 if (data_ir.padded()) { |
| 2324 builder.WriteUInt8(data_ir.padding_payload_len() >> 8); | |
| 2325 } | |
| 2326 if (data_ir.pad_low()) { | |
| 2327 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2309 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 2328 } | 2310 } |
| 2329 builder.OverwriteLength(*this, num_padding_fields + | 2311 builder.OverwriteLength(*this, num_padding_fields + |
| 2330 data_ir.data().length() + data_ir.padding_payload_len()); | 2312 data_ir.data().length() + data_ir.padding_payload_len()); |
| 2331 } else { | 2313 } else { |
| 2332 builder.OverwriteLength(*this, data_ir.data().length()); | 2314 builder.OverwriteLength(*this, data_ir.data().length()); |
| 2333 } | 2315 } |
| 2334 DCHECK_EQ(frame_size, builder.length()); | 2316 DCHECK_EQ(frame_size, builder.length()); |
| 2335 return builder.take(); | 2317 return builder.take(); |
| 2336 } | 2318 } |
| 2337 | 2319 |
| 2338 SpdySerializedFrame* SpdyFramer::SerializeSynStream( | 2320 SpdySerializedFrame* SpdyFramer::SerializeSynStream( |
| 2339 const SpdySynStreamIR& syn_stream) { | 2321 const SpdySynStreamIR& syn_stream) { |
| 2322 DCHECK_GE(SPDY3, protocol_version()); |
| 2340 uint8 flags = 0; | 2323 uint8 flags = 0; |
| 2341 if (syn_stream.fin()) { | 2324 if (syn_stream.fin()) { |
| 2342 flags |= CONTROL_FLAG_FIN; | 2325 flags |= CONTROL_FLAG_FIN; |
| 2343 } | 2326 } |
| 2344 if (syn_stream.unidirectional()) { | 2327 if (syn_stream.unidirectional()) { |
| 2345 // TODO(hkhalil): invalid for HTTP2. | 2328 // TODO(hkhalil): invalid for HTTP2. |
| 2346 flags |= CONTROL_FLAG_UNIDIRECTIONAL; | 2329 flags |= CONTROL_FLAG_UNIDIRECTIONAL; |
| 2347 } | 2330 } |
| 2348 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now | |
| 2349 // we never expect to have to overflow into a CONTINUATION frame. | |
| 2350 if (protocol_version() > SPDY3) { | |
| 2351 flags |= HEADERS_FLAG_PRIORITY; | |
| 2352 flags |= HEADERS_FLAG_END_HEADERS; | |
| 2353 } | |
| 2354 | 2331 |
| 2355 // Sanitize priority. | 2332 // Sanitize priority. |
| 2356 uint8 priority = syn_stream.priority(); | 2333 uint8 priority = syn_stream.priority(); |
| 2357 if (priority > GetLowestPriority()) { | 2334 if (priority > GetLowestPriority()) { |
| 2358 DLOG(DFATAL) << "Priority out-of-bounds."; | 2335 DLOG(DFATAL) << "Priority out-of-bounds."; |
| 2359 priority = GetLowestPriority(); | 2336 priority = GetLowestPriority(); |
| 2360 } | 2337 } |
| 2361 | 2338 |
| 2362 // The size of this frame, including variable-length name-value block. | 2339 // The size of this frame, including variable-length name-value block. |
| 2363 size_t size = GetSynStreamMinimumSize(); | 2340 size_t size = GetSynStreamMinimumSize() + |
| 2364 | 2341 GetSerializedLength(syn_stream.name_value_block()); |
| 2365 string hpack_encoding; | |
| 2366 if (protocol_version() > SPDY3) { | |
| 2367 if (enable_compression_) { | |
| 2368 GetHpackEncoder()->EncodeHeaderSet( | |
| 2369 syn_stream.name_value_block(), &hpack_encoding); | |
| 2370 } else { | |
| 2371 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | |
| 2372 syn_stream.name_value_block(), &hpack_encoding); | |
| 2373 } | |
| 2374 size += hpack_encoding.size(); | |
| 2375 } else { | |
| 2376 size += GetSerializedLength(syn_stream.name_value_block()); | |
| 2377 } | |
| 2378 | 2342 |
| 2379 SpdyFrameBuilder builder(size, protocol_version()); | 2343 SpdyFrameBuilder builder(size, protocol_version()); |
| 2380 if (protocol_version() <= SPDY3) { | 2344 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); |
| 2381 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); | 2345 builder.WriteUInt32(syn_stream.stream_id()); |
| 2382 builder.WriteUInt32(syn_stream.stream_id()); | 2346 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
| 2383 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 2347 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); |
| 2384 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); | 2348 builder.WriteUInt8(0); // Unused byte where credential slot used to be. |
| 2385 builder.WriteUInt8(0); // Unused byte where credential slot used to be. | |
| 2386 } else { | |
| 2387 builder.BeginNewFrame(*this, | |
| 2388 HEADERS, | |
| 2389 flags, | |
| 2390 syn_stream.stream_id()); | |
| 2391 // TODO(jgraettinger): Plumb priorities and stream dependencies. | |
| 2392 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. | |
| 2393 builder.WriteUInt8(MapPriorityToWeight(priority)); | |
| 2394 } | |
| 2395 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 2349 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
| 2396 if (protocol_version() > SPDY3) { | 2350 SerializeNameValueBlock(&builder, syn_stream); |
| 2397 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | |
| 2398 } else { | |
| 2399 SerializeNameValueBlock(&builder, syn_stream); | |
| 2400 } | |
| 2401 | 2351 |
| 2402 if (debug_visitor_) { | 2352 if (debug_visitor_) { |
| 2403 const size_t payload_len = protocol_version() > SPDY3 ? | 2353 const size_t payload_len = |
| 2404 hpack_encoding.size() : | |
| 2405 GetSerializedLength(protocol_version(), | 2354 GetSerializedLength(protocol_version(), |
| 2406 &(syn_stream.name_value_block())); | 2355 &(syn_stream.name_value_block())); |
| 2407 // SPDY 4 reports this compression as a SYN_STREAM compression. | 2356 // SPDY 4 reports this compression as a SYN_STREAM compression. |
| 2408 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), | 2357 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), |
| 2409 SYN_STREAM, | 2358 SYN_STREAM, |
| 2410 payload_len, | 2359 payload_len, |
| 2411 builder.length()); | 2360 builder.length()); |
| 2412 } | 2361 } |
| 2413 | 2362 |
| 2414 return builder.take(); | 2363 return builder.take(); |
| 2415 } | 2364 } |
| 2416 | 2365 |
| 2417 SpdySerializedFrame* SpdyFramer::SerializeSynReply( | 2366 SpdySerializedFrame* SpdyFramer::SerializeSynReply( |
| 2418 const SpdySynReplyIR& syn_reply) { | 2367 const SpdySynReplyIR& syn_reply) { |
| 2368 DCHECK_GE(SPDY3, protocol_version()); |
| 2419 uint8 flags = 0; | 2369 uint8 flags = 0; |
| 2420 if (syn_reply.fin()) { | 2370 if (syn_reply.fin()) { |
| 2421 flags |= CONTROL_FLAG_FIN; | 2371 flags |= CONTROL_FLAG_FIN; |
| 2422 } | 2372 } |
| 2423 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now | |
| 2424 // we never expect to have to overflow into a CONTINUATION frame. | |
| 2425 if (protocol_version() > SPDY3) { | |
| 2426 flags |= HEADERS_FLAG_END_HEADERS; | |
| 2427 } | |
| 2428 | 2373 |
| 2429 // The size of this frame, including variable-length name-value block. | 2374 // The size of this frame, including variable-length name-value block. |
| 2430 size_t size = GetSynReplyMinimumSize(); | 2375 const size_t size = GetSynReplyMinimumSize() + |
| 2431 | 2376 GetSerializedLength(syn_reply.name_value_block()); |
| 2432 string hpack_encoding; | |
| 2433 if (protocol_version() > SPDY3) { | |
| 2434 if (enable_compression_) { | |
| 2435 GetHpackEncoder()->EncodeHeaderSet( | |
| 2436 syn_reply.name_value_block(), &hpack_encoding); | |
| 2437 } else { | |
| 2438 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | |
| 2439 syn_reply.name_value_block(), &hpack_encoding); | |
| 2440 } | |
| 2441 size += hpack_encoding.size(); | |
| 2442 } else { | |
| 2443 size += GetSerializedLength(syn_reply.name_value_block()); | |
| 2444 } | |
| 2445 | 2377 |
| 2446 SpdyFrameBuilder builder(size, protocol_version()); | 2378 SpdyFrameBuilder builder(size, protocol_version()); |
| 2447 if (protocol_version() <= SPDY3) { | 2379 if (protocol_version() <= SPDY3) { |
| 2448 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); | 2380 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); |
| 2449 builder.WriteUInt32(syn_reply.stream_id()); | 2381 builder.WriteUInt32(syn_reply.stream_id()); |
| 2450 } else { | 2382 } else { |
| 2451 builder.BeginNewFrame(*this, | 2383 builder.BeginNewFrame(*this, |
| 2452 HEADERS, | 2384 HEADERS, |
| 2453 flags, | 2385 flags, |
| 2454 syn_reply.stream_id()); | 2386 syn_reply.stream_id()); |
| 2455 } | 2387 } |
| 2456 if (protocol_version() < SPDY3) { | 2388 if (protocol_version() < SPDY3) { |
| 2457 builder.WriteUInt16(0); // Unused. | 2389 builder.WriteUInt16(0); // Unused. |
| 2458 } | 2390 } |
| 2459 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); | 2391 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); |
| 2460 if (protocol_version() > SPDY3) { | 2392 SerializeNameValueBlock(&builder, syn_reply); |
| 2461 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | |
| 2462 } else { | |
| 2463 SerializeNameValueBlock(&builder, syn_reply); | |
| 2464 } | |
| 2465 | 2393 |
| 2466 if (debug_visitor_) { | 2394 if (debug_visitor_) { |
| 2467 const size_t payload_len = protocol_version() > SPDY3 ? | 2395 const size_t payload_len = GetSerializedLength( |
| 2468 hpack_encoding.size() : | 2396 protocol_version(), &(syn_reply.name_value_block())); |
| 2469 GetSerializedLength(protocol_version(), | |
| 2470 &(syn_reply.name_value_block())); | |
| 2471 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), | 2397 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), |
| 2472 SYN_REPLY, | 2398 SYN_REPLY, |
| 2473 payload_len, | 2399 payload_len, |
| 2474 builder.length()); | 2400 builder.length()); |
| 2475 } | 2401 } |
| 2476 | 2402 |
| 2477 return builder.take(); | 2403 return builder.take(); |
| 2478 } | 2404 } |
| 2479 | 2405 |
| 2480 SpdySerializedFrame* SpdyFramer::SerializeRstStream( | 2406 SpdySerializedFrame* SpdyFramer::SerializeRstStream( |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2518 if (settings.clear_settings()) { | 2444 if (settings.clear_settings()) { |
| 2519 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; | 2445 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; |
| 2520 } | 2446 } |
| 2521 } else { | 2447 } else { |
| 2522 if (settings.is_ack()) { | 2448 if (settings.is_ack()) { |
| 2523 flags |= SETTINGS_FLAG_ACK; | 2449 flags |= SETTINGS_FLAG_ACK; |
| 2524 } | 2450 } |
| 2525 } | 2451 } |
| 2526 const SpdySettingsIR::ValueMap* values = &(settings.values()); | 2452 const SpdySettingsIR::ValueMap* values = &(settings.values()); |
| 2527 | 2453 |
| 2528 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5); | 2454 size_t setting_size = SpdyConstants::GetSettingSize(protocol_version()); |
| 2529 // Size, in bytes, of this SETTINGS frame. | 2455 // Size, in bytes, of this SETTINGS frame. |
| 2530 const size_t size = GetSettingsMinimumSize() + | 2456 const size_t size = GetSettingsMinimumSize() + |
| 2531 (values->size() * setting_size); | 2457 (values->size() * setting_size); |
| 2532 SpdyFrameBuilder builder(size, protocol_version()); | 2458 SpdyFrameBuilder builder(size, protocol_version()); |
| 2533 if (protocol_version() <= SPDY3) { | 2459 if (protocol_version() <= SPDY3) { |
| 2534 builder.WriteControlFrameHeader(*this, SETTINGS, flags); | 2460 builder.WriteControlFrameHeader(*this, SETTINGS, flags); |
| 2535 } else { | 2461 } else { |
| 2536 builder.BeginNewFrame(*this, SETTINGS, flags, 0); | 2462 builder.BeginNewFrame(*this, SETTINGS, flags, 0); |
| 2537 } | 2463 } |
| 2538 | 2464 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 2555 } | 2481 } |
| 2556 if (it->second.persisted) { | 2482 if (it->second.persisted) { |
| 2557 setting_flags |= SETTINGS_FLAG_PERSISTED; | 2483 setting_flags |= SETTINGS_FLAG_PERSISTED; |
| 2558 } | 2484 } |
| 2559 SettingsFlagsAndId flags_and_id( | 2485 SettingsFlagsAndId flags_and_id( |
| 2560 setting_flags, | 2486 setting_flags, |
| 2561 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); | 2487 SpdyConstants::SerializeSettingId(protocol_version(), it->first)); |
| 2562 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); | 2488 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); |
| 2563 builder.WriteBytes(&id_and_flags_wire, 4); | 2489 builder.WriteBytes(&id_and_flags_wire, 4); |
| 2564 } else { | 2490 } else { |
| 2565 builder.WriteUInt8(SpdyConstants::SerializeSettingId(protocol_version(), | 2491 builder.WriteUInt16(SpdyConstants::SerializeSettingId(protocol_version(), |
| 2566 it->first)); | 2492 it->first)); |
| 2567 } | 2493 } |
| 2568 builder.WriteUInt32(it->second.value); | 2494 builder.WriteUInt32(it->second.value); |
| 2569 } | 2495 } |
| 2570 DCHECK_EQ(size, builder.length()); | 2496 DCHECK_EQ(size, builder.length()); |
| 2571 return builder.take(); | 2497 return builder.take(); |
| 2572 } | 2498 } |
| 2573 | 2499 |
| 2574 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { | 2500 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { |
| 2575 SpdyFrameBuilder builder(GetPingSize(), protocol_version()); | 2501 SpdyFrameBuilder builder(GetPingSize(), protocol_version()); |
| 2576 if (protocol_version() <= SPDY3) { | 2502 if (protocol_version() <= SPDY3) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2641 | 2567 |
| 2642 // The size of this frame, including variable-length name-value block. | 2568 // The size of this frame, including variable-length name-value block. |
| 2643 size_t size = GetHeadersMinimumSize(); | 2569 size_t size = GetHeadersMinimumSize(); |
| 2644 | 2570 |
| 2645 uint32 priority = headers.priority(); | 2571 uint32 priority = headers.priority(); |
| 2646 if (headers.has_priority()) { | 2572 if (headers.has_priority()) { |
| 2647 if (priority > GetLowestPriority()) { | 2573 if (priority > GetLowestPriority()) { |
| 2648 DLOG(DFATAL) << "Priority out-of-bounds."; | 2574 DLOG(DFATAL) << "Priority out-of-bounds."; |
| 2649 priority = GetLowestPriority(); | 2575 priority = GetLowestPriority(); |
| 2650 } | 2576 } |
| 2651 size += 4; | 2577 size += 5; |
| 2652 } | 2578 } |
| 2653 | 2579 |
| 2654 string hpack_encoding; | 2580 string hpack_encoding; |
| 2655 if (protocol_version() > SPDY3) { | 2581 if (protocol_version() > SPDY3) { |
| 2656 if (enable_compression_) { | 2582 if (enable_compression_) { |
| 2657 GetHpackEncoder()->EncodeHeaderSet( | 2583 GetHpackEncoder()->EncodeHeaderSet( |
| 2658 headers.name_value_block(), &hpack_encoding); | 2584 headers.name_value_block(), &hpack_encoding); |
| 2659 } else { | 2585 } else { |
| 2660 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | 2586 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( |
| 2661 headers.name_value_block(), &hpack_encoding); | 2587 headers.name_value_block(), &hpack_encoding); |
| (...skipping 10 matching lines...) Expand all Loading... |
| 2672 | 2598 |
| 2673 SpdyFrameBuilder builder(size, protocol_version()); | 2599 SpdyFrameBuilder builder(size, protocol_version()); |
| 2674 if (protocol_version() <= SPDY3) { | 2600 if (protocol_version() <= SPDY3) { |
| 2675 builder.WriteControlFrameHeader(*this, HEADERS, flags); | 2601 builder.WriteControlFrameHeader(*this, HEADERS, flags); |
| 2676 builder.WriteUInt32(headers.stream_id()); | 2602 builder.WriteUInt32(headers.stream_id()); |
| 2677 } else { | 2603 } else { |
| 2678 builder.BeginNewFrame(*this, | 2604 builder.BeginNewFrame(*this, |
| 2679 HEADERS, | 2605 HEADERS, |
| 2680 flags, | 2606 flags, |
| 2681 headers.stream_id()); | 2607 headers.stream_id()); |
| 2682 if (headers.has_priority()) { | |
| 2683 // TODO(jgraettinger): Plumb priorities and stream dependencies. | |
| 2684 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. | |
| 2685 builder.WriteUInt8(MapPriorityToWeight(priority)); | |
| 2686 } | |
| 2687 } | 2608 } |
| 2688 if (protocol_version() <= SPDY2) { | 2609 if (protocol_version() <= SPDY2) { |
| 2689 builder.WriteUInt16(0); // Unused. | 2610 builder.WriteUInt16(0); // Unused. |
| 2690 } | 2611 } |
| 2691 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2612 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
| 2692 | 2613 |
| 2693 if (protocol_version() > SPDY3) { | 2614 if (protocol_version() > SPDY3) { |
| 2615 if (headers.has_priority()) { |
| 2616 // TODO(jgraettinger): Plumb priorities and stream dependencies. |
| 2617 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. |
| 2618 builder.WriteUInt8(MapPriorityToWeight(priority)); |
| 2619 } |
| 2694 WritePayloadWithContinuation(&builder, | 2620 WritePayloadWithContinuation(&builder, |
| 2695 hpack_encoding, | 2621 hpack_encoding, |
| 2696 headers.stream_id(), | 2622 headers.stream_id(), |
| 2697 HEADERS); | 2623 HEADERS); |
| 2698 } else { | 2624 } else { |
| 2699 SerializeNameValueBlock(&builder, headers); | 2625 SerializeNameValueBlock(&builder, headers); |
| 2700 } | 2626 } |
| 2701 | 2627 |
| 2702 if (debug_visitor_) { | 2628 if (debug_visitor_) { |
| 2703 const size_t payload_len = protocol_version() > SPDY3 ? | 2629 const size_t payload_len = protocol_version() > SPDY3 ? |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2740 SpdyFrame* SpdyFramer::SerializePushPromise( | 2666 SpdyFrame* SpdyFramer::SerializePushPromise( |
| 2741 const SpdyPushPromiseIR& push_promise) { | 2667 const SpdyPushPromiseIR& push_promise) { |
| 2742 DCHECK_LT(SPDY3, protocol_version()); | 2668 DCHECK_LT(SPDY3, protocol_version()); |
| 2743 uint8 flags = 0; | 2669 uint8 flags = 0; |
| 2744 // This will get overwritten if we overflow into a CONTINUATION frame. | 2670 // This will get overwritten if we overflow into a CONTINUATION frame. |
| 2745 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2671 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
| 2746 // The size of this frame, including variable-length name-value block. | 2672 // The size of this frame, including variable-length name-value block. |
| 2747 size_t size = GetPushPromiseMinimumSize(); | 2673 size_t size = GetPushPromiseMinimumSize(); |
| 2748 | 2674 |
| 2749 string hpack_encoding; | 2675 string hpack_encoding; |
| 2750 if (protocol_version() > SPDY3) { | 2676 if (enable_compression_) { |
| 2751 if (enable_compression_) { | 2677 GetHpackEncoder()->EncodeHeaderSet( |
| 2752 GetHpackEncoder()->EncodeHeaderSet( | 2678 push_promise.name_value_block(), &hpack_encoding); |
| 2753 push_promise.name_value_block(), &hpack_encoding); | |
| 2754 } else { | |
| 2755 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( | |
| 2756 push_promise.name_value_block(), &hpack_encoding); | |
| 2757 } | |
| 2758 size += hpack_encoding.size(); | |
| 2759 if (size > GetControlFrameBufferMaxSize()) { | |
| 2760 size += GetNumberRequiredContinuationFrames(size) * | |
| 2761 GetContinuationMinimumSize(); | |
| 2762 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | |
| 2763 } | |
| 2764 } else { | 2679 } else { |
| 2765 size += GetSerializedLength(push_promise.name_value_block()); | 2680 GetHpackEncoder()->EncodeHeaderSetWithoutCompression( |
| 2681 push_promise.name_value_block(), &hpack_encoding); |
| 2682 } |
| 2683 size += hpack_encoding.size(); |
| 2684 if (size > GetControlFrameBufferMaxSize()) { |
| 2685 size += GetNumberRequiredContinuationFrames(size) * |
| 2686 GetContinuationMinimumSize(); |
| 2687 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
| 2766 } | 2688 } |
| 2767 | 2689 |
| 2768 SpdyFrameBuilder builder(size, protocol_version()); | 2690 SpdyFrameBuilder builder(size, protocol_version()); |
| 2769 builder.BeginNewFrame(*this, | 2691 builder.BeginNewFrame(*this, |
| 2770 PUSH_PROMISE, | 2692 PUSH_PROMISE, |
| 2771 flags, | 2693 flags, |
| 2772 push_promise.stream_id()); | 2694 push_promise.stream_id()); |
| 2773 builder.WriteUInt32(push_promise.promised_stream_id()); | 2695 builder.WriteUInt32(push_promise.promised_stream_id()); |
| 2774 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); | 2696 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); |
| 2775 | 2697 |
| 2776 if (protocol_version() > SPDY3) { | 2698 WritePayloadWithContinuation(&builder, |
| 2777 WritePayloadWithContinuation(&builder, | 2699 hpack_encoding, |
| 2778 hpack_encoding, | 2700 push_promise.stream_id(), |
| 2779 push_promise.stream_id(), | 2701 PUSH_PROMISE); |
| 2780 PUSH_PROMISE); | |
| 2781 } else { | |
| 2782 SerializeNameValueBlock(&builder, push_promise); | |
| 2783 } | |
| 2784 | 2702 |
| 2785 if (debug_visitor_) { | 2703 if (debug_visitor_) { |
| 2786 const size_t payload_len = protocol_version() > SPDY3 ? | |
| 2787 hpack_encoding.size() : | |
| 2788 GetSerializedLength(protocol_version(), | |
| 2789 &(push_promise.name_value_block())); | |
| 2790 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2704 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), |
| 2791 PUSH_PROMISE, payload_len, builder.length()); | 2705 PUSH_PROMISE, hpack_encoding.size(), builder.length()); |
| 2792 } | 2706 } |
| 2793 | 2707 |
| 2794 return builder.take(); | 2708 return builder.take(); |
| 2795 } | 2709 } |
| 2796 | 2710 |
| 2797 // TODO(jgraettinger): This implementation is incorrect. The continuation | 2711 // TODO(jgraettinger): This implementation is incorrect. The continuation |
| 2798 // frame continues a previously-begun HPACK encoding; it doesn't begin a | 2712 // frame continues a previously-begun HPACK encoding; it doesn't begin a |
| 2799 // new one. Figure out whether it makes sense to keep SerializeContinuation(). | 2713 // new one. Figure out whether it makes sense to keep SerializeContinuation(). |
| 2800 SpdyFrame* SpdyFramer::SerializeContinuation( | 2714 SpdyFrame* SpdyFramer::SerializeContinuation( |
| 2801 const SpdyContinuationIR& continuation) { | 2715 const SpdyContinuationIR& continuation) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2849 builder.WriteUInt8(altsvc.protocol_id().length()); | 2763 builder.WriteUInt8(altsvc.protocol_id().length()); |
| 2850 builder.WriteBytes(altsvc.protocol_id().data(), | 2764 builder.WriteBytes(altsvc.protocol_id().data(), |
| 2851 altsvc.protocol_id().length()); | 2765 altsvc.protocol_id().length()); |
| 2852 builder.WriteUInt8(altsvc.host().length()); | 2766 builder.WriteUInt8(altsvc.host().length()); |
| 2853 builder.WriteBytes(altsvc.host().data(), altsvc.host().length()); | 2767 builder.WriteBytes(altsvc.host().data(), altsvc.host().length()); |
| 2854 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length()); | 2768 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length()); |
| 2855 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); | 2769 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); |
| 2856 return builder.take(); | 2770 return builder.take(); |
| 2857 } | 2771 } |
| 2858 | 2772 |
| 2773 SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) { |
| 2774 DCHECK_LT(SPDY3, protocol_version()); |
| 2775 size_t size = GetPrioritySize(); |
| 2776 |
| 2777 SpdyFrameBuilder builder(size, protocol_version()); |
| 2778 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id()); |
| 2779 |
| 2780 // Make sure the highest-order bit in the parent stream id is zeroed out. |
| 2781 uint32 parent_stream_id = priority.parent_stream_id() & 0x7fffffff; |
| 2782 uint32 exclusive = priority.exclusive() ? 0x80000000 : 0; |
| 2783 // Set the one-bit exclusivity flag. |
| 2784 uint32 flag_and_parent_id = parent_stream_id | exclusive; |
| 2785 builder.WriteUInt32(flag_and_parent_id); |
| 2786 builder.WriteUInt8(priority.weight()); |
| 2787 DCHECK_EQ(GetPrioritySize(), builder.length()); |
| 2788 return builder.take(); |
| 2789 } |
| 2790 |
| 2859 namespace { | 2791 namespace { |
| 2860 | 2792 |
| 2861 class FrameSerializationVisitor : public SpdyFrameVisitor { | 2793 class FrameSerializationVisitor : public SpdyFrameVisitor { |
| 2862 public: | 2794 public: |
| 2863 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} | 2795 explicit FrameSerializationVisitor(SpdyFramer* framer) : framer_(framer) {} |
| 2864 virtual ~FrameSerializationVisitor() {} | 2796 virtual ~FrameSerializationVisitor() {} |
| 2865 | 2797 |
| 2866 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } | 2798 SpdySerializedFrame* ReleaseSerializedFrame() { return frame_.release(); } |
| 2867 | 2799 |
| 2868 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { | 2800 virtual void VisitData(const SpdyDataIR& data) OVERRIDE { |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2900 const SpdyPushPromiseIR& push_promise) OVERRIDE { | 2832 const SpdyPushPromiseIR& push_promise) OVERRIDE { |
| 2901 frame_.reset(framer_->SerializePushPromise(push_promise)); | 2833 frame_.reset(framer_->SerializePushPromise(push_promise)); |
| 2902 } | 2834 } |
| 2903 virtual void VisitContinuation( | 2835 virtual void VisitContinuation( |
| 2904 const SpdyContinuationIR& continuation) OVERRIDE { | 2836 const SpdyContinuationIR& continuation) OVERRIDE { |
| 2905 frame_.reset(framer_->SerializeContinuation(continuation)); | 2837 frame_.reset(framer_->SerializeContinuation(continuation)); |
| 2906 } | 2838 } |
| 2907 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE { | 2839 virtual void VisitAltSvc(const SpdyAltSvcIR& altsvc) OVERRIDE { |
| 2908 frame_.reset(framer_->SerializeAltSvc(altsvc)); | 2840 frame_.reset(framer_->SerializeAltSvc(altsvc)); |
| 2909 } | 2841 } |
| 2842 virtual void VisitPriority(const SpdyPriorityIR& priority) OVERRIDE { |
| 2843 frame_.reset(framer_->SerializePriority(priority)); |
| 2844 } |
| 2910 | 2845 |
| 2911 private: | 2846 private: |
| 2912 SpdyFramer* framer_; | 2847 SpdyFramer* framer_; |
| 2913 scoped_ptr<SpdySerializedFrame> frame_; | 2848 scoped_ptr<SpdySerializedFrame> frame_; |
| 2914 }; | 2849 }; |
| 2915 | 2850 |
| 2916 } // namespace | 2851 } // namespace |
| 2917 | 2852 |
| 2918 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { | 2853 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { |
| 2919 FrameSerializationVisitor visitor(this); | 2854 FrameSerializationVisitor visitor(this); |
| (...skipping 342 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 builder->Seek(compressed_size); | 3197 builder->Seek(compressed_size); |
| 3263 builder->RewriteLength(*this); | 3198 builder->RewriteLength(*this); |
| 3264 | 3199 |
| 3265 pre_compress_bytes.Add(uncompressed_len); | 3200 pre_compress_bytes.Add(uncompressed_len); |
| 3266 post_compress_bytes.Add(compressed_size); | 3201 post_compress_bytes.Add(compressed_size); |
| 3267 | 3202 |
| 3268 compressed_frames.Increment(); | 3203 compressed_frames.Increment(); |
| 3269 } | 3204 } |
| 3270 | 3205 |
| 3271 } // namespace net | 3206 } // namespace net |
| OLD | NEW |