Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(58)

Side by Side Diff: net/spdy/spdy_framer.cc

Issue 483843004: HTTP2 draft 13: support unknown frame types and settings types as extensions. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@merge_1
Patch Set: Add mock OnUnknownFrame to SpdyFramerVisitor in spdy_interface_test. Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698