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 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
490 case PING: | 490 case PING: |
491 return "PING"; | 491 return "PING"; |
492 case GOAWAY: | 492 case GOAWAY: |
493 return "GOAWAY"; | 493 return "GOAWAY"; |
494 case HEADERS: | 494 case HEADERS: |
495 return "HEADERS"; | 495 return "HEADERS"; |
496 case WINDOW_UPDATE: | 496 case WINDOW_UPDATE: |
497 return "WINDOW_UPDATE"; | 497 return "WINDOW_UPDATE"; |
498 case CREDENTIAL: | 498 case CREDENTIAL: |
499 return "CREDENTIAL"; | 499 return "CREDENTIAL"; |
500 case BLOCKED: | |
501 return "BLOCKED"; | |
502 case PUSH_PROMISE: | 500 case PUSH_PROMISE: |
503 return "PUSH_PROMISE"; | 501 return "PUSH_PROMISE"; |
504 case CONTINUATION: | 502 case CONTINUATION: |
505 return "CONTINUATION"; | 503 return "CONTINUATION"; |
| 504 case PRIORITY: |
| 505 return "PRIORITY"; |
506 case ALTSVC: | 506 case ALTSVC: |
507 return "ALTSVC"; | 507 return "ALTSVC"; |
508 case PRIORITY: | 508 case BLOCKED: |
509 return "PRIORITY"; | 509 return "BLOCKED"; |
510 } | 510 } |
511 return "UNKNOWN_CONTROL_TYPE"; | 511 return "UNKNOWN_CONTROL_TYPE"; |
512 } | 512 } |
513 | 513 |
514 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { | 514 size_t SpdyFramer::ProcessInput(const char* data, size_t len) { |
515 DCHECK(visitor_); | 515 DCHECK(visitor_); |
516 DCHECK(data); | 516 DCHECK(data); |
517 | 517 |
518 size_t original_len = len; | 518 size_t original_len = len; |
519 do { | 519 do { |
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
830 } | 830 } |
831 | 831 |
832 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { | 832 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { |
833 DCHECK_EQ(SPDY_NO_ERROR, error_code_); | 833 DCHECK_EQ(SPDY_NO_ERROR, error_code_); |
834 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); | 834 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); |
835 | 835 |
836 // TODO(mlavan): Either remove credential frames from the code entirely, | 836 // TODO(mlavan): Either remove credential frames from the code entirely, |
837 // or add them to parsing + serialization methods for SPDY3. | 837 // or add them to parsing + serialization methods for SPDY3. |
838 // Early detection of deprecated frames that we ignore. | 838 // Early detection of deprecated frames that we ignore. |
839 if (protocol_version() <= SPDY3) { | 839 if (protocol_version() <= SPDY3) { |
840 | |
841 if (control_frame_type_field == CREDENTIAL) { | 840 if (control_frame_type_field == CREDENTIAL) { |
842 current_frame_type_ = CREDENTIAL; | 841 current_frame_type_ = CREDENTIAL; |
843 DCHECK_EQ(SPDY3, protocol_version()); | 842 DCHECK_EQ(SPDY3, protocol_version()); |
844 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; | 843 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; |
845 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); | 844 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
846 return; | 845 return; |
847 } | 846 } |
848 } | 847 } |
849 | 848 |
850 if (!SpdyConstants::IsValidFrameType(protocol_version(), | 849 if (!SpdyConstants::IsValidFrameType(protocol_version(), |
851 control_frame_type_field)) { | 850 control_frame_type_field)) { |
852 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field | 851 if (protocol_version() <= SPDY3) { |
853 << " (protocol version: " << protocol_version() << ")"; | 852 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field |
854 set_error(SPDY_INVALID_CONTROL_FRAME); | 853 << " (protocol version: " << protocol_version() << ")"; |
855 return; | 854 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 855 return; |
| 856 } else { |
| 857 // In HTTP2 we ignore unknown frame types for extensibility, as long as |
| 858 // the rest of the control frame header is valid. |
| 859 // We rely on the visitor to check validity of current_frame_stream_id_. |
| 860 bool valid_stream = visitor_->OnUnknownFrame(current_frame_stream_id_, |
| 861 control_frame_type_field); |
| 862 if (valid_stream) { |
| 863 DVLOG(1) << "Ignoring unknown frame type."; |
| 864 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); |
| 865 } else { |
| 866 // Report an invalid frame error and close the stream if the |
| 867 // stream_id is not valid. |
| 868 DLOG(WARNING) << "Unknown control frame type " |
| 869 << control_frame_type_field |
| 870 << " received on invalid stream " |
| 871 << current_frame_stream_id_; |
| 872 set_error(SPDY_INVALID_CONTROL_FRAME); |
| 873 } |
| 874 return; |
| 875 } |
856 } | 876 } |
857 | 877 |
858 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), | 878 current_frame_type_ = SpdyConstants::ParseFrameType(protocol_version(), |
859 control_frame_type_field); | 879 control_frame_type_field); |
860 | 880 |
861 // Do some sanity checking on the control frame sizes and flags. | 881 // Do some sanity checking on the control frame sizes and flags. |
862 switch (current_frame_type_) { | 882 switch (current_frame_type_) { |
863 case SYN_STREAM: | 883 case SYN_STREAM: |
864 if (current_frame_length_ < GetSynStreamMinimumSize()) { | 884 if (current_frame_length_ < GetSynStreamMinimumSize()) { |
865 set_error(SPDY_INVALID_CONTROL_FRAME); | 885 set_error(SPDY_INVALID_CONTROL_FRAME); |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
963 case WINDOW_UPDATE: | 983 case WINDOW_UPDATE: |
964 if (current_frame_length_ != GetWindowUpdateSize()) { | 984 if (current_frame_length_ != GetWindowUpdateSize()) { |
965 set_error(SPDY_INVALID_CONTROL_FRAME); | 985 set_error(SPDY_INVALID_CONTROL_FRAME); |
966 } else if (current_frame_flags_ != 0) { | 986 } else if (current_frame_flags_ != 0) { |
967 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 987 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
968 } | 988 } |
969 break; | 989 break; |
970 case BLOCKED: | 990 case BLOCKED: |
971 if (current_frame_length_ != GetBlockedSize() || | 991 if (current_frame_length_ != GetBlockedSize() || |
972 protocol_version() <= SPDY3) { | 992 protocol_version() <= SPDY3) { |
973 // TODO(mlavan): BLOCKED frames are no longer part of SPDY4. | |
974 set_error(SPDY_INVALID_CONTROL_FRAME); | 993 set_error(SPDY_INVALID_CONTROL_FRAME); |
975 } else if (current_frame_flags_ != 0) { | 994 } else if (current_frame_flags_ != 0) { |
976 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 995 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); |
977 } | 996 } |
978 break; | 997 break; |
979 case PUSH_PROMISE: | 998 case PUSH_PROMISE: |
980 if (current_frame_length_ < GetPushPromiseMinimumSize()) { | 999 if (current_frame_length_ < GetPushPromiseMinimumSize()) { |
981 set_error(SPDY_INVALID_CONTROL_FRAME); | 1000 set_error(SPDY_INVALID_CONTROL_FRAME); |
982 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { | 1001 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { |
983 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); | 1002 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(); | 1744 flags = id_and_flags.flags(); |
1726 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); | 1745 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); |
1727 } else { | 1746 } else { |
1728 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); | 1747 id_field = ntohs(*(reinterpret_cast<const uint16*>(data))); |
1729 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); | 1748 value = ntohl(*(reinterpret_cast<const uint32*>(data + 2))); |
1730 } | 1749 } |
1731 | 1750 |
1732 // Validate id. | 1751 // Validate id. |
1733 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { | 1752 if (!SpdyConstants::IsValidSettingId(protocol_version(), id_field)) { |
1734 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; | 1753 DLOG(WARNING) << "Unknown SETTINGS ID: " << id_field; |
1735 return false; | 1754 if (protocol_version() <= SPDY3) { |
| 1755 return false; |
| 1756 } else { |
| 1757 // In HTTP2 we ignore unknown settings for extensibility. |
| 1758 return true; |
| 1759 } |
1736 } | 1760 } |
1737 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); | 1761 id = SpdyConstants::ParseSettingId(protocol_version(), id_field); |
1738 | 1762 |
1739 if (protocol_version() <= SPDY3) { | 1763 if (protocol_version() <= SPDY3) { |
1740 // Detect duplicates. | 1764 // Detect duplicates. |
1741 if (id <= settings_scratch_.last_setting_id) { | 1765 if (id <= settings_scratch_.last_setting_id) { |
1742 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id | 1766 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id |
1743 << " in " << display_protocol_ << " SETTINGS frame " | 1767 << " in " << display_protocol_ << " SETTINGS frame " |
1744 << "(last setting id was " | 1768 << "(last setting id was " |
1745 << settings_scratch_.last_setting_id << ")."; | 1769 << settings_scratch_.last_setting_id << ")."; |
(...skipping 1474 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3220 builder->Seek(compressed_size); | 3244 builder->Seek(compressed_size); |
3221 builder->RewriteLength(*this); | 3245 builder->RewriteLength(*this); |
3222 | 3246 |
3223 pre_compress_bytes.Add(uncompressed_len); | 3247 pre_compress_bytes.Add(uncompressed_len); |
3224 post_compress_bytes.Add(compressed_size); | 3248 post_compress_bytes.Add(compressed_size); |
3225 | 3249 |
3226 compressed_frames.Increment(); | 3250 compressed_frames.Increment(); |
3227 } | 3251 } |
3228 | 3252 |
3229 } // namespace net | 3253 } // namespace net |
OLD | NEW |