| 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 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 67 const uint8 kNoFlags = 0; | 67 const uint8 kNoFlags = 0; |
| 68 | 68 |
| 69 // Wire sizes of priority payloads. | 69 // Wire sizes of priority payloads. |
| 70 const size_t kPriorityDependencyPayloadSize = 4; | 70 const size_t kPriorityDependencyPayloadSize = 4; |
| 71 const size_t kPriorityWeightPayloadSize = 1; | 71 const size_t kPriorityWeightPayloadSize = 1; |
| 72 | 72 |
| 73 } // namespace | 73 } // namespace |
| 74 | 74 |
| 75 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1); | 75 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1); |
| 76 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; | 76 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; |
| 77 // The size of the control frame buffer. Must be >= the minimum size of the |
| 77 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for | 78 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for |
| 78 // calculation details. | 79 // calculation details. |
| 79 const size_t SpdyFramer::kControlFrameBufferSize = 18; | 80 const size_t SpdyFramer::kControlFrameBufferSize = 19; |
| 80 | 81 |
| 81 #ifdef DEBUG_SPDY_STATE_CHANGES | 82 #ifdef DEBUG_SPDY_STATE_CHANGES |
| 82 #define CHANGE_STATE(newstate) \ | 83 #define CHANGE_STATE(newstate) \ |
| 83 do { \ | 84 do { \ |
| 84 DVLOG(1) << "Changing state from: " \ | 85 DVLOG(1) << "Changing state from: " \ |
| 85 << StateToString(state_) \ | 86 << StateToString(state_) \ |
| 86 << " to " << StateToString(newstate) << "\n"; \ | 87 << " to " << StateToString(newstate) << "\n"; \ |
| 87 DCHECK(state_ != SPDY_ERROR); \ | 88 DCHECK(state_ != SPDY_ERROR); \ |
| 88 DCHECK_EQ(previous_state_, state_); \ | 89 DCHECK_EQ(previous_state_, state_); \ |
| 89 previous_state_ = state_; \ | 90 previous_state_ = state_; \ |
| (...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 current_frame_type_ = DATA; | 182 current_frame_type_ = DATA; |
| 182 current_frame_flags_ = 0; | 183 current_frame_flags_ = 0; |
| 183 current_frame_length_ = 0; | 184 current_frame_length_ = 0; |
| 184 current_frame_stream_id_ = kInvalidStream; | 185 current_frame_stream_id_ = kInvalidStream; |
| 185 settings_scratch_.Reset(); | 186 settings_scratch_.Reset(); |
| 186 altsvc_scratch_.Reset(); | 187 altsvc_scratch_.Reset(); |
| 187 remaining_padding_payload_length_ = 0; | 188 remaining_padding_payload_length_ = 0; |
| 188 } | 189 } |
| 189 | 190 |
| 190 size_t SpdyFramer::GetDataFrameMinimumSize() const { | 191 size_t SpdyFramer::GetDataFrameMinimumSize() const { |
| 191 return SpdyConstants::GetDataFrameMinimumSize(); | 192 return SpdyConstants::GetDataFrameMinimumSize(protocol_version()); |
| 192 } | 193 } |
| 193 | 194 |
| 194 // Size, in bytes, of the control frame header. | 195 // Size, in bytes, of the control frame header. |
| 195 size_t SpdyFramer::GetControlFrameHeaderSize() const { | 196 size_t SpdyFramer::GetControlFrameHeaderSize() const { |
| 196 return SpdyConstants::GetControlFrameHeaderSize(protocol_version()); | 197 return SpdyConstants::GetControlFrameHeaderSize(protocol_version()); |
| 197 } | 198 } |
| 198 | 199 |
| 199 size_t SpdyFramer::GetSynStreamMinimumSize() const { | 200 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
| 200 // Size, in bytes, of a SYN_STREAM frame not including the variable-length | 201 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
| 201 // name-value block. | 202 // name-value block. |
| (...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 490 case PING: | 491 case PING: |
| 491 return "PING"; | 492 return "PING"; |
| 492 case GOAWAY: | 493 case GOAWAY: |
| 493 return "GOAWAY"; | 494 return "GOAWAY"; |
| 494 case HEADERS: | 495 case HEADERS: |
| 495 return "HEADERS"; | 496 return "HEADERS"; |
| 496 case WINDOW_UPDATE: | 497 case WINDOW_UPDATE: |
| 497 return "WINDOW_UPDATE"; | 498 return "WINDOW_UPDATE"; |
| 498 case CREDENTIAL: | 499 case CREDENTIAL: |
| 499 return "CREDENTIAL"; | 500 return "CREDENTIAL"; |
| 500 case BLOCKED: | |
| 501 return "BLOCKED"; | |
| 502 case PUSH_PROMISE: | 501 case PUSH_PROMISE: |
| 503 return "PUSH_PROMISE"; | 502 return "PUSH_PROMISE"; |
| 504 case CONTINUATION: | 503 case CONTINUATION: |
| 505 return "CONTINUATION"; | 504 return "CONTINUATION"; |
| 505 case PRIORITY: |
| 506 return "PRIORITY"; |
| 506 case ALTSVC: | 507 case ALTSVC: |
| 507 return "ALTSVC"; | 508 return "ALTSVC"; |
| 508 case PRIORITY: | 509 case BLOCKED: |
| 509 return "PRIORITY"; | 510 return "BLOCKED"; |
| 510 } | 511 } |
| 511 return "UNKNOWN_CONTROL_TYPE"; | 512 return "UNKNOWN_CONTROL_TYPE"; |
| 512 } | 513 } |
| 513 | 514 |
| 514 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { | 515 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { |
| 515 DCHECK(visitor_); | 516 DCHECK(visitor_); |
| 516 DCHECK(data); | 517 DCHECK(data); |
| 517 | 518 |
| 518 size_t original_len = len; | 519 size_t original_len = len; |
| 519 do { | 520 do { |
| (...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 715 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 716 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
| 716 DCHECK(successful_read); | 717 DCHECK(successful_read); |
| 717 | 718 |
| 718 uint32 length_field = 0; | 719 uint32 length_field = 0; |
| 719 successful_read = reader->ReadUInt24(&length_field); | 720 successful_read = reader->ReadUInt24(&length_field); |
| 720 DCHECK(successful_read); | 721 DCHECK(successful_read); |
| 721 remaining_data_length_ = length_field; | 722 remaining_data_length_ = length_field; |
| 722 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); | 723 current_frame_length_ = remaining_data_length_ + reader->GetBytesConsumed(); |
| 723 } else { | 724 } else { |
| 724 version = protocol_version(); | 725 version = protocol_version(); |
| 725 uint16 length_field = 0; | 726 uint32 length_field = 0; |
| 726 bool successful_read = reader->ReadUInt16(&length_field); | 727 bool successful_read = reader->ReadUInt24(&length_field); |
| 727 DCHECK(successful_read); | 728 DCHECK(successful_read); |
| 728 | 729 |
| 729 uint8 control_frame_type_field_uint8 = | 730 uint8 control_frame_type_field_uint8 = |
| 730 SpdyConstants::DataFrameType(protocol_version()); | 731 SpdyConstants::DataFrameType(protocol_version()); |
| 731 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); | 732 successful_read = reader->ReadUInt8(&control_frame_type_field_uint8); |
| 732 DCHECK(successful_read); | 733 DCHECK(successful_read); |
| 733 // We check control_frame_type_field's validity in | 734 // We check control_frame_type_field's validity in |
| 734 // ProcessControlFrameHeader(). | 735 // ProcessControlFrameHeader(). |
| 735 control_frame_type_field = control_frame_type_field_uint8; | 736 control_frame_type_field = control_frame_type_field_uint8; |
| 736 is_control_frame = (protocol_version() > SPDY3) ? | 737 is_control_frame = (protocol_version() > SPDY3) ? |
| 737 control_frame_type_field != | 738 control_frame_type_field != |
| 738 SpdyConstants::SerializeFrameType(protocol_version(), DATA) : | 739 SpdyConstants::SerializeFrameType(protocol_version(), DATA) : |
| 739 control_frame_type_field != 0; | 740 control_frame_type_field != 0; |
| 740 | 741 |
| 741 if (is_control_frame) { | 742 if (is_control_frame) { |
| 742 current_frame_length_ = length_field + GetControlFrameHeaderSize(); | 743 current_frame_length_ = length_field + GetControlFrameHeaderSize(); |
| 743 } else { | 744 } else { |
| 744 current_frame_length_ = length_field + GetDataFrameMinimumSize(); | 745 current_frame_length_ = length_field + GetDataFrameMinimumSize(); |
| 745 } | 746 } |
| 746 | 747 |
| 747 successful_read = reader->ReadUInt8(¤t_frame_flags_); | 748 successful_read = reader->ReadUInt8(¤t_frame_flags_); |
| 748 DCHECK(successful_read); | 749 DCHECK(successful_read); |
| 749 | 750 |
| (...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 830 } | 831 } |
| 831 | 832 |
| 832 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 833 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
| 833 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 834 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
| 834 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 835 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
| 835 | 836 |
| 836 // TODO(mlavan): Either remove credential frames from the code entirely, | 837 // TODO(mlavan): Either remove credential frames from the code entirely, |
| 837 // or add them to parsing + serialization methods for SPDY3. | 838 // or add them to parsing + serialization methods for SPDY3. |
| 838 // Early detection of deprecated frames that we ignore. | 839 // Early detection of deprecated frames that we ignore. |
| 839 if (protocol_version() <= SPDY3) { | 840 if (protocol_version() <= SPDY3) { |
| 840 | |
| 841 if (control_frame_type_field == CREDENTIAL) { | 841 if (control_frame_type_field == CREDENTIAL) { |
| 842 current_frame_type_ = CREDENTIAL; | 842 current_frame_type_ = CREDENTIAL; |
| 843 DCHECK_EQ(SPDY3, protocol_version()); | 843 DCHECK_EQ(SPDY3, protocol_version()); |
| 844 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | 844 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
| 845 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 845 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 846 return; | 846 return; |
| 847 } | 847 } |
| 848 } | 848 } |
| 849 | 849 |
| 850 if (!SpdyConstants::IsValidFrameType(protocol_version(), | 850 if (!SpdyConstants::IsValidFrameType(protocol_version(), |
| 851 control_frame_type_field)) { | 851 control_frame_type_field)) { |
| 852 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field | 852 if (protocol_version() <= SPDY3) { |
| 853 << " (protocol version: " << protocol_version() << ")"; | 853 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
| 854 set_error(SPDY_INVALID_CONTROL_FRAME); | 854 << " (protocol version: " << protocol_version() << ")"; |
| 855 return; | 855 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 856 return; |
| 857 } else { |
| 858 // In HTTP2 we ignore unknown frame types for extensibility, as long as |
| 859 // the rest of the control frame header is valid. |
| 860 // We rely on the visitor to check validity of current_frame_stream_id_. |
| 861 bool valid_stream = visitor_->OnUnknownFrame(current_frame_stream_id_, |
| 862 control_frame_type_field); |
| 863 if (valid_stream) { |
| 864 DVLOG(1) << "Ignoring unknown frame type."; |
| 865 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 866 } else { |
| 867 // Report an invalid frame error and close the stream if the |
| 868 // stream_id is not valid. |
| 869 DLOG(WARNING) << "Unknown control frame type " |
| 870 << control_frame_type_field |
| 871 << " received on invalid stream " |
| 872 << current_frame_stream_id_; |
| 873 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 874 } |
| 875 return; |
| 876 } |
| 856 } | 877 } |
| 857 | 878 |
| 858 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), | 879 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
| 859 control_frame_type_field); | 880 control_frame_type_field); |
| 860 | 881 |
| 861 // Do some sanity checking on the control frame sizes and flags. | 882 // Do some sanity checking on the control frame sizes and flags. |
| 862 switch (current_frame_type_) { | 883 switch (current_frame_type_) { |
| 863 case SYN_STREAM: | 884 case SYN_STREAM: |
| 864 if (current_frame_length_ < GetSynStreamMinimumSize()) { | 885 if (current_frame_length_ < GetSynStreamMinimumSize()) { |
| 865 set_error(SPDY_INVALID_CONTROL_FRAME); | 886 set_error(SPDY_INVALID_CONTROL_FRAME); |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 break; | 961 break; |
| 941 } | 962 } |
| 942 case HEADERS: | 963 case HEADERS: |
| 943 { | 964 { |
| 944 size_t min_size = GetHeadersMinimumSize(); | 965 size_t min_size = GetHeadersMinimumSize(); |
| 945 if (protocol_version() > SPDY3 && | 966 if (protocol_version() > SPDY3 && |
| 946 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { | 967 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { |
| 947 min_size += 4; | 968 min_size += 4; |
| 948 } | 969 } |
| 949 if (current_frame_length_ < min_size) { | 970 if (current_frame_length_ < min_size) { |
| 971 // TODO(mlavan): check here for HEADERS with no payload? |
| 972 // (not allowed in SPDY4) |
| 950 set_error(SPDY_INVALID_CONTROL_FRAME); | 973 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 951 } else if (protocol_version() <= SPDY3 && | 974 } else if (protocol_version() <= SPDY3 && |
| 952 current_frame_flags_ & ~CONTROL_FLAG_FIN) { | 975 current_frame_flags_ & ~CONTROL_FLAG_FIN) { |
| 953 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 954 } else if (protocol_version() > SPDY3 && | 977 } else if (protocol_version() > SPDY3 && |
| 955 current_frame_flags_ & | 978 current_frame_flags_ & |
| 956 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | | 979 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | |
| 957 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | | 980 HEADERS_FLAG_END_HEADERS | HEADERS_FLAG_END_SEGMENT | |
| 958 HEADERS_FLAG_PADDED)) { | 981 HEADERS_FLAG_PADDED)) { |
| 959 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 982 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 960 } | 983 } |
| 961 } | 984 } |
| 962 break; | 985 break; |
| 963 case WINDOW_UPDATE: | 986 case WINDOW_UPDATE: |
| 964 if (current_frame_length_ != GetWindowUpdateSize()) { | 987 if (current_frame_length_ != GetWindowUpdateSize()) { |
| 965 set_error(SPDY_INVALID_CONTROL_FRAME); | 988 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 966 } else if (current_frame_flags_ != 0) { | 989 } else if (current_frame_flags_ != 0) { |
| 967 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 990 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 968 } | 991 } |
| 969 break; | 992 break; |
| 970 case BLOCKED: | 993 case BLOCKED: |
| 971 if (current_frame_length_ != GetBlockedSize() || | 994 if (current_frame_length_ != GetBlockedSize() || |
| 972 protocol_version() <= SPDY3) { | 995 protocol_version() <= SPDY3) { |
| 973 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. | |
| 974 set_error(SPDY_INVALID_CONTROL_FRAME); | 996 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 975 } else if (current_frame_flags_ != 0) { | 997 } else if (current_frame_flags_ != 0) { |
| 976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 998 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| 977 } | 999 } |
| 978 break; | 1000 break; |
| 979 case PUSH_PROMISE: | 1001 case PUSH_PROMISE: |
| 980 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 1002 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
| 981 set_error(SPDY_INVALID_CONTROL_FRAME); | 1003 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 982 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 1004 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
| 983 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 1005 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
| (...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1725 flags = id_and_flags.flags(); | 1747 flags = id_and_flags.flags(); |
| 1726 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1748 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
| 1727 } else { | 1749 } else { |
| 1728 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); | 1750 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); |
| 1729 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); | 1751 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); |
| 1730 } | 1752 } |
| 1731 | 1753 |
| 1732 // Validate id. | 1754 // Validate id. |
| 1733 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { | 1755 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
| 1734 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1756 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
| 1735 return false; | 1757 if (protocol_version() <= SPDY3) { |
| 1758 return false; |
| 1759 } else { |
| 1760 // In HTTP2 we ignore unknown settings for extensibility. |
| 1761 return true; |
| 1762 } |
| 1736 } | 1763 } |
| 1737 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); | 1764 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); |
| 1738 | 1765 |
| 1739 if (protocol_version() <= SPDY3) { | 1766 if (protocol_version() <= SPDY3) { |
| 1740 // Detect duplicates. | 1767 // Detect duplicates. |
| 1741 if (id <= settings_scratch_.last_setting_id) { | 1768 if (id <= settings_scratch_.last_setting_id) { |
| 1742 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id | 1769 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id |
| 1743 << " in " << display_protocol_ << " SETTINGS frame " | 1770 << " in " << display_protocol_ << " SETTINGS frame " |
| 1744 << "(last setting id was " | 1771 << "(last setting id was " |
| 1745 << settings_scratch_.last_setting_id << ")."; | 1772 << settings_scratch_.last_setting_id << ")."; |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1870 SpdyGoAwayStatus status = GOAWAY_OK; | 1897 SpdyGoAwayStatus status = GOAWAY_OK; |
| 1871 if (protocol_version() >= SPDY3) { | 1898 if (protocol_version() >= SPDY3) { |
| 1872 uint32 status_raw = GOAWAY_OK; | 1899 uint32 status_raw = GOAWAY_OK; |
| 1873 successful_read = reader.ReadUInt32(&status_raw); | 1900 successful_read = reader.ReadUInt32(&status_raw); |
| 1874 DCHECK(successful_read); | 1901 DCHECK(successful_read); |
| 1875 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(), | 1902 if (SpdyConstants::IsValidGoAwayStatus(protocol_version(), |
| 1876 status_raw)) { | 1903 status_raw)) { |
| 1877 status = SpdyConstants::ParseGoAwayStatus(protocol_version(), | 1904 status = SpdyConstants::ParseGoAwayStatus(protocol_version(), |
| 1878 status_raw); | 1905 status_raw); |
| 1879 } else { | 1906 } else { |
| 1880 DCHECK(false); | |
| 1881 // Throw an error for SPDY4+, keep liberal behavior | |
| 1882 // for earlier versions. | |
| 1883 if (protocol_version() > SPDY3) { | 1907 if (protocol_version() > SPDY3) { |
| 1884 DLOG(WARNING) << "Invalid GO_AWAY status " << status_raw; | 1908 // Treat unrecognized status codes as INTERNAL_ERROR as |
| 1885 set_error(SPDY_INVALID_CONTROL_FRAME); | 1909 // recommended by the HTTP/2 spec. |
| 1886 return 0; | 1910 status = GOAWAY_INTERNAL_ERROR; |
| 1887 } | 1911 } |
| 1888 } | 1912 } |
| 1889 } | 1913 } |
| 1890 // Finished parsing the GOAWAY header, call frame handler. | 1914 // Finished parsing the GOAWAY header, call frame handler. |
| 1891 visitor_->OnGoAway(current_frame_stream_id_, status); | 1915 visitor_->OnGoAway(current_frame_stream_id_, status); |
| 1892 } | 1916 } |
| 1893 } | 1917 } |
| 1894 | 1918 |
| 1895 // Handle remaining data as opaque. | 1919 // Handle remaining data as opaque. |
| 1896 bool processed_successfully = true; | 1920 bool processed_successfully = true; |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1939 } | 1963 } |
| 1940 | 1964 |
| 1941 SpdyRstStreamStatus status = RST_STREAM_INVALID; | 1965 SpdyRstStreamStatus status = RST_STREAM_INVALID; |
| 1942 uint32 status_raw = status; | 1966 uint32 status_raw = status; |
| 1943 bool successful_read = reader.ReadUInt32(&status_raw); | 1967 bool successful_read = reader.ReadUInt32(&status_raw); |
| 1944 DCHECK(successful_read); | 1968 DCHECK(successful_read); |
| 1945 if (SpdyConstants::IsValidRstStreamStatus(protocol_version(), | 1969 if (SpdyConstants::IsValidRstStreamStatus(protocol_version(), |
| 1946 status_raw)) { | 1970 status_raw)) { |
| 1947 status = static_cast<SpdyRstStreamStatus>(status_raw); | 1971 status = static_cast<SpdyRstStreamStatus>(status_raw); |
| 1948 } else { | 1972 } else { |
| 1949 // Throw an error for SPDY4+, keep liberal behavior | |
| 1950 // for earlier versions. | |
| 1951 if (protocol_version() > SPDY3) { | 1973 if (protocol_version() > SPDY3) { |
| 1952 DLOG(WARNING) << "Invalid RST_STREAM status " << status_raw; | 1974 // Treat unrecognized status codes as INTERNAL_ERROR as |
| 1953 set_error(SPDY_INVALID_CONTROL_FRAME); | 1975 // recommended by the HTTP/2 spec. |
| 1954 return 0; | 1976 status = RST_STREAM_INTERNAL_ERROR; |
| 1955 } | 1977 } |
| 1956 } | 1978 } |
| 1957 // Finished parsing the RST_STREAM header, call frame handler. | 1979 // Finished parsing the RST_STREAM header, call frame handler. |
| 1958 visitor_->OnRstStream(current_frame_stream_id_, status); | 1980 visitor_->OnRstStream(current_frame_stream_id_, status); |
| 1959 } | 1981 } |
| 1960 } | 1982 } |
| 1961 | 1983 |
| 1962 // Handle remaining data as opaque. | 1984 // Handle remaining data as opaque. |
| 1963 bool processed_successfully = true; | 1985 bool processed_successfully = true; |
| 1964 if (len > 0) { | 1986 if (len > 0) { |
| (...skipping 1260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3225 builder->Seek(compressed_size); | 3247 builder->Seek(compressed_size); |
| 3226 builder->RewriteLength(*this); | 3248 builder->RewriteLength(*this); |
| 3227 | 3249 |
| 3228 pre_compress_bytes.Add(uncompressed_len); | 3250 pre_compress_bytes.Add(uncompressed_len); |
| 3229 post_compress_bytes.Add(compressed_size); | 3251 post_compress_bytes.Add(compressed_size); |
| 3230 | 3252 |
| 3231 compressed_frames.Increment(); | 3253 compressed_frames.Increment(); |
| 3232 } | 3254 } |
| 3233 | 3255 |
| 3234 } // namespace net | 3256 } // namespace net |
| OLD | NEW |