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

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

Issue 247243003: SPDY: Use SpdyMajorVersion rather than ints for SPDY version number. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Also include cr/64899106 Created 6 years, 8 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 | Annotate | Revision Log
« 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 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't
6 // constantly adding and subtracting header sizes; this is ugly and error- 6 // constantly adding and subtracting header sizes; this is ugly and error-
7 // prone. 7 // prone.
8 8
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 10
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
74 #else 74 #else
75 #define CHANGE_STATE(newstate) \ 75 #define CHANGE_STATE(newstate) \
76 do { \ 76 do { \
77 DCHECK(state_ != SPDY_ERROR); \ 77 DCHECK(state_ != SPDY_ERROR); \
78 DCHECK_EQ(previous_state_, state_); \ 78 DCHECK_EQ(previous_state_, state_); \
79 previous_state_ = state_; \ 79 previous_state_ = state_; \
80 state_ = newstate; \ 80 state_ = newstate; \
81 } while (false) 81 } while (false)
82 #endif 82 #endif
83 83
84 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(int version, 84 SettingsFlagsAndId SettingsFlagsAndId::FromWireFormat(
85 uint32 wire) { 85 SpdyMajorVersion version, uint32 wire) {
86 if (version < 3) { 86 if (version < SPDY3) {
87 ConvertFlagsAndIdForSpdy2(&wire); 87 ConvertFlagsAndIdForSpdy2(&wire);
88 } 88 }
89 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff); 89 return SettingsFlagsAndId(ntohl(wire) >> 24, ntohl(wire) & 0x00ffffff);
90 } 90 }
91 91
92 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id) 92 SettingsFlagsAndId::SettingsFlagsAndId(uint8 flags, uint32 id)
93 : flags_(flags), id_(id & 0x00ffffff) { 93 : flags_(flags), id_(id & 0x00ffffff) {
94 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id; 94 LOG_IF(DFATAL, id > (1u << 24)) << "SPDY setting ID too large: " << id;
95 } 95 }
96 96
97 uint32 SettingsFlagsAndId::GetWireFormat(int version) const { 97 uint32 SettingsFlagsAndId::GetWireFormat(SpdyMajorVersion version)
98 const {
98 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24); 99 uint32 wire = htonl(id_ & 0x00ffffff) | htonl(flags_ << 24);
99 if (version < 3) { 100 if (version < SPDY3) {
100 ConvertFlagsAndIdForSpdy2(&wire); 101 ConvertFlagsAndIdForSpdy2(&wire);
101 } 102 }
102 return wire; 103 return wire;
103 } 104 }
104 105
105 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field. 106 // SPDY 2 had a bug in it with respect to byte ordering of id/flags field.
106 // This method is used to preserve buggy behavior and works on both 107 // This method is used to preserve buggy behavior and works on both
107 // little-endian and big-endian hosts. 108 // little-endian and big-endian hosts.
108 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3 109 // This method is also bidirectional (can be used to translate SPDY 2 to SPDY 3
109 // as well as vice versa). 110 // as well as vice versa).
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 248
248 size_t SpdyFramer::GetGoAwayMinimumSize() const { 249 size_t SpdyFramer::GetGoAwayMinimumSize() const {
249 // Size, in bytes, of this GOAWAY frame. Calculated as: 250 // Size, in bytes, of this GOAWAY frame. Calculated as:
250 // 1. Control frame header size 251 // 1. Control frame header size
251 size_t size = GetControlFrameHeaderSize(); 252 size_t size = GetControlFrameHeaderSize();
252 253
253 // 2. Last good stream id (4 bytes) 254 // 2. Last good stream id (4 bytes)
254 size += 4; 255 size += 4;
255 256
256 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes) 257 // 3. SPDY 3+ GOAWAY frames also contain a status (4 bytes)
257 if (protocol_version() >= 3) { 258 if (protocol_version() >= SPDY3) {
258 size += 4; 259 size += 4;
259 } 260 }
260 261
261 return size; 262 return size;
262 } 263 }
263 264
264 size_t SpdyFramer::GetHeadersMinimumSize() const { 265 size_t SpdyFramer::GetHeadersMinimumSize() const {
265 // Size, in bytes, of a HEADERS frame not including the variable-length 266 // Size, in bytes, of a HEADERS frame not including the variable-length
266 // name-value block. 267 // name-value block.
267 size_t size = GetControlFrameHeaderSize(); 268 size_t size = GetControlFrameHeaderSize();
(...skipping 18 matching lines...) Expand all
286 // control frame header + 4 (stream id) + 4 (delta) 287 // control frame header + 4 (stream id) + 4 (delta)
287 return GetControlFrameHeaderSize() + 8; 288 return GetControlFrameHeaderSize() + 8;
288 } else { 289 } else {
289 // Calculated as: 290 // Calculated as:
290 // frame prefix + 4 (delta) 291 // frame prefix + 4 (delta)
291 return GetControlFrameHeaderSize() + 4; 292 return GetControlFrameHeaderSize() + 4;
292 } 293 }
293 } 294 }
294 295
295 size_t SpdyFramer::GetBlockedSize() const { 296 size_t SpdyFramer::GetBlockedSize() const {
296 DCHECK_LE(4, protocol_version()); 297 DCHECK_LT(SPDY3, protocol_version());
297 // Size, in bytes, of a BLOCKED frame. 298 // Size, in bytes, of a BLOCKED frame.
298 // The BLOCKED frame has no payload beyond the control frame header. 299 // The BLOCKED frame has no payload beyond the control frame header.
299 return GetControlFrameHeaderSize(); 300 return GetControlFrameHeaderSize();
300 } 301 }
301 302
302 size_t SpdyFramer::GetPushPromiseMinimumSize() const { 303 size_t SpdyFramer::GetPushPromiseMinimumSize() const {
303 DCHECK_LE(4, protocol_version()); 304 DCHECK_LT(SPDY3, protocol_version());
304 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block. 305 // Size, in bytes, of a PUSH_PROMISE frame, sans the embedded header block.
305 // Calculated as frame prefix + 4 (promised stream id). 306 // Calculated as frame prefix + 4 (promised stream id).
306 return GetControlFrameHeaderSize() + 4; 307 return GetControlFrameHeaderSize() + 4;
307 } 308 }
308 309
309 size_t SpdyFramer::GetContinuationMinimumSize() const { 310 size_t SpdyFramer::GetContinuationMinimumSize() const {
310 // Size, in bytes, of a CONTINUATION frame not including the variable-length 311 // Size, in bytes, of a CONTINUATION frame not including the variable-length
311 // headers fragments. 312 // headers fragments.
312 return GetControlFrameHeaderSize(); 313 return GetControlFrameHeaderSize();
313 } 314 }
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
630 631
631 uint16 control_frame_type_field = DATA; 632 uint16 control_frame_type_field = DATA;
632 // ProcessControlFrameHeader() will set current_frame_type_ to the 633 // ProcessControlFrameHeader() will set current_frame_type_ to the
633 // correct value if this is a valid control frame. 634 // correct value if this is a valid control frame.
634 current_frame_type_ = DATA; 635 current_frame_type_ = DATA;
635 if (protocol_version() <= SPDY3) { 636 if (protocol_version() <= SPDY3) {
636 bool successful_read = reader->ReadUInt16(&version); 637 bool successful_read = reader->ReadUInt16(&version);
637 DCHECK(successful_read); 638 DCHECK(successful_read);
638 is_control_frame = (version & kControlFlagMask) != 0; 639 is_control_frame = (version & kControlFlagMask) != 0;
639 version &= ~kControlFlagMask; // Only valid for control frames. 640 version &= ~kControlFlagMask; // Only valid for control frames.
641 if (is_control_frame &&
642 version >= SpdyConstants::SerializeMajorVersion(SPDY_MIN_VERSION) &&
643 version <= SpdyConstants::SerializeMajorVersion(SPDY_MAX_VERSION)) {
644 version = SpdyConstants::ParseMajorVersion(version);
645 }
640 646
641 if (is_control_frame) { 647 if (is_control_frame) {
642 // We check control_frame_type_field's validity in 648 // We check control_frame_type_field's validity in
643 // ProcessControlFrameHeader(). 649 // ProcessControlFrameHeader().
644 successful_read = reader->ReadUInt16(&control_frame_type_field); 650 successful_read = reader->ReadUInt16(&control_frame_type_field);
645 } else { 651 } else {
646 reader->Rewind(); 652 reader->Rewind();
647 successful_read = reader->ReadUInt31(&current_frame_stream_id_); 653 successful_read = reader->ReadUInt31(&current_frame_stream_id_);
648 } 654 }
649 DCHECK(successful_read); 655 DCHECK(successful_read);
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
750 if (current_frame_flags_ & DATA_FLAG_FIN) { 756 if (current_frame_flags_ & DATA_FLAG_FIN) {
751 visitor_->OnStreamFrameData( 757 visitor_->OnStreamFrameData(
752 current_frame_stream_id_, NULL, 0, true); 758 current_frame_stream_id_, NULL, 0, true);
753 } 759 }
754 CHANGE_STATE(SPDY_AUTO_RESET); 760 CHANGE_STATE(SPDY_AUTO_RESET);
755 } 761 }
756 } 762 }
757 } else if (version != protocol_version()) { 763 } else if (version != protocol_version()) {
758 // We check version before we check validity: version can never be 764 // We check version before we check validity: version can never be
759 // 'invalid', it can only be unsupported. 765 // 'invalid', it can only be unsupported.
760 DVLOG(1) << "Unsupported SPDY version " << version 766 DVLOG(1) << "Unsupported SPDY version "
767 << version
761 << " (expected " << protocol_version() << ")"; 768 << " (expected " << protocol_version() << ")";
762 set_error(SPDY_UNSUPPORTED_VERSION); 769 set_error(SPDY_UNSUPPORTED_VERSION);
763 } else { 770 } else {
764 ProcessControlFrameHeader(control_frame_type_field); 771 ProcessControlFrameHeader(control_frame_type_field);
765 } 772 }
766 773
767 return original_len - len; 774 return original_len - len;
768 } 775 }
769 776
770 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { 777 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
(...skipping 147 matching lines...) Expand 10 before | Expand all | Expand 10 after
918 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 925 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
919 set_error(SPDY_INVALID_CONTROL_FRAME); 926 set_error(SPDY_INVALID_CONTROL_FRAME);
920 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) { 927 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
921 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 928 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
922 } else if (protocol_version() > SPDY3 && current_frame_flags_ & 929 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
923 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { 930 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) {
924 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
925 } 932 }
926 break; 933 break;
927 case CONTINUATION: 934 case CONTINUATION:
928 if (current_frame_length_ < GetContinuationMinimumSize()) { 935 if (current_frame_length_ < GetContinuationMinimumSize() ||
936 protocol_version() <= SPDY3) {
929 set_error(SPDY_INVALID_CONTROL_FRAME); 937 set_error(SPDY_INVALID_CONTROL_FRAME);
930 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { 938 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) {
931 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 939 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
932 } 940 }
933 break; 941 break;
934 default: 942 default:
935 LOG(WARNING) << "Valid " << display_protocol_ 943 LOG(WARNING) << "Valid " << display_protocol_
936 << " control frame with unhandled type: " 944 << " control frame with unhandled type: "
937 << current_frame_type_; 945 << current_frame_type_;
938 // This branch should be unreachable because of the frame type bounds 946 // This branch should be unreachable because of the frame type bounds
(...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after
1034 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_, 1042 memcpy(current_frame_buffer_.get() + current_frame_buffer_length_,
1035 *data, 1043 *data,
1036 bytes_to_read); 1044 bytes_to_read);
1037 current_frame_buffer_length_ += bytes_to_read; 1045 current_frame_buffer_length_ += bytes_to_read;
1038 *data += bytes_to_read; 1046 *data += bytes_to_read;
1039 *len -= bytes_to_read; 1047 *len -= bytes_to_read;
1040 } 1048 }
1041 return bytes_to_read; 1049 return bytes_to_read;
1042 } 1050 }
1043 1051
1044 size_t SpdyFramer::GetSerializedLength(const int spdy_version, 1052 size_t SpdyFramer::GetSerializedLength(
1045 const SpdyHeaderBlock* headers) { 1053 const SpdyMajorVersion spdy_version,
1054 const SpdyHeaderBlock* headers) {
1046 const size_t num_name_value_pairs_size 1055 const size_t num_name_value_pairs_size
1047 = (spdy_version < 3) ? sizeof(uint16) : sizeof(uint32); 1056 = (spdy_version < SPDY3) ? sizeof(uint16) : sizeof(uint32);
1048 const size_t length_of_name_size = num_name_value_pairs_size; 1057 const size_t length_of_name_size = num_name_value_pairs_size;
1049 const size_t length_of_value_size = num_name_value_pairs_size; 1058 const size_t length_of_value_size = num_name_value_pairs_size;
1050 1059
1051 size_t total_length = num_name_value_pairs_size; 1060 size_t total_length = num_name_value_pairs_size;
1052 for (SpdyHeaderBlock::const_iterator it = headers->begin(); 1061 for (SpdyHeaderBlock::const_iterator it = headers->begin();
1053 it != headers->end(); 1062 it != headers->end();
1054 ++it) { 1063 ++it) {
1055 // We add space for the length of the name and the length of the value as 1064 // We add space for the length of the name and the length of the value as
1056 // well as the length of the name and the length of the value. 1065 // well as the length of the name and the length of the value.
1057 total_length += length_of_name_size + it->first.size() + 1066 total_length += length_of_name_size + it->first.size() +
1058 length_of_value_size + it->second.size(); 1067 length_of_value_size + it->second.size();
1059 } 1068 }
1060 return total_length; 1069 return total_length;
1061 } 1070 }
1062 1071
1063 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame, 1072 void SpdyFramer::WriteHeaderBlock(SpdyFrameBuilder* frame,
1064 const int spdy_version, 1073 const SpdyMajorVersion spdy_version,
1065 const SpdyHeaderBlock* headers) { 1074 const SpdyHeaderBlock* headers) {
1066 if (spdy_version < 3) { 1075 if (spdy_version < SPDY3) {
1067 frame->WriteUInt16(headers->size()); // Number of headers. 1076 frame->WriteUInt16(headers->size()); // Number of headers.
1068 } else { 1077 } else {
1069 frame->WriteUInt32(headers->size()); // Number of headers. 1078 frame->WriteUInt32(headers->size()); // Number of headers.
1070 } 1079 }
1071 SpdyHeaderBlock::const_iterator it; 1080 SpdyHeaderBlock::const_iterator it;
1072 for (it = headers->begin(); it != headers->end(); ++it) { 1081 for (it = headers->begin(); it != headers->end(); ++it) {
1073 if (spdy_version < 3) { 1082 if (spdy_version < SPDY3) {
1074 frame->WriteString(it->first); 1083 frame->WriteString(it->first);
1075 frame->WriteString(it->second); 1084 frame->WriteString(it->second);
1076 } else { 1085 } else {
1077 frame->WriteStringPiece32(it->first); 1086 frame->WriteStringPiece32(it->first);
1078 frame->WriteStringPiece32(it->second); 1087 frame->WriteStringPiece32(it->second);
1079 } 1088 }
1080 } 1089 }
1081 } 1090 }
1082 1091
1083 // TODO(phajdan.jr): Clean up after we no longer need 1092 // TODO(phajdan.jr): Clean up after we no longer need
(...skipping 775 matching lines...) Expand 10 before | Expand all | Expand 10 after
1859 } 1868 }
1860 1869
1861 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) { 1870 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
1862 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_); 1871 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
1863 1872
1864 size_t original_len = len; 1873 size_t original_len = len;
1865 if (remaining_padding_length_fields_ == 0) { 1874 if (remaining_padding_length_fields_ == 0) {
1866 DCHECK_EQ(remaining_padding_payload_length_, 0u); 1875 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1867 bool pad_low = false; 1876 bool pad_low = false;
1868 bool pad_high = false; 1877 bool pad_high = false;
1869 if (current_frame_flags_ & net::DATA_FLAG_PAD_LOW) { 1878 if (current_frame_flags_ & DATA_FLAG_PAD_LOW) {
1870 pad_low = true; 1879 pad_low = true;
1871 ++remaining_padding_length_fields_; 1880 ++remaining_padding_length_fields_;
1872 } 1881 }
1873 if (current_frame_flags_ & net::DATA_FLAG_PAD_HIGH) { 1882 if (current_frame_flags_ & DATA_FLAG_PAD_HIGH) {
1874 pad_high = true; 1883 pad_high = true;
1875 ++remaining_padding_length_fields_; 1884 ++remaining_padding_length_fields_;
1876 } 1885 }
1877 if ((pad_high && !pad_low) || 1886 if ((pad_high && !pad_low) ||
1878 remaining_data_length_ < remaining_padding_length_fields_) { 1887 remaining_data_length_ < remaining_padding_length_fields_) {
1879 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 1888 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1880 return 0; 1889 return 0;
1881 } 1890 }
1882 } 1891 }
1883 1892
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after
2671 return uncompressed_length; 2680 return uncompressed_length;
2672 } 2681 }
2673 z_stream* compressor = GetHeaderCompressor(); 2682 z_stream* compressor = GetHeaderCompressor();
2674 // Since we'll be performing lots of flushes when compressing the data, 2683 // Since we'll be performing lots of flushes when compressing the data,
2675 // zlib's lower bounds may be insufficient. 2684 // zlib's lower bounds may be insufficient.
2676 return 2 * deflateBound(compressor, uncompressed_length); 2685 return 2 * deflateBound(compressor, uncompressed_length);
2677 } 2686 }
2678 2687
2679 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { 2688 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
2680 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); 2689 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
2681 DCHECK_GT(protocol_version(), net::SPDY3); 2690 DCHECK_GT(protocol_version(), SPDY3);
2682 DCHECK_GT(size, kMaxControlFrameSize); 2691 DCHECK_GT(size, kMaxControlFrameSize);
2683 size_t overflow = size - kMaxControlFrameSize; 2692 size_t overflow = size - kMaxControlFrameSize;
2684 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1; 2693 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
2685 } 2694 }
2686 2695
2687 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, 2696 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2688 const string& hpack_encoding, 2697 const string& hpack_encoding,
2689 SpdyStreamId stream_id, 2698 SpdyStreamId stream_id,
2690 SpdyFrameType type) { 2699 SpdyFrameType type) {
2691 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize(); 2700 const size_t kMaxControlFrameSize = GetControlFrameBufferMaxSize();
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
2981 builder->Seek(compressed_size); 2990 builder->Seek(compressed_size);
2982 builder->RewriteLength(*this); 2991 builder->RewriteLength(*this);
2983 2992
2984 pre_compress_bytes.Add(uncompressed_len); 2993 pre_compress_bytes.Add(uncompressed_len);
2985 post_compress_bytes.Add(compressed_size); 2994 post_compress_bytes.Add(compressed_size);
2986 2995
2987 compressed_frames.Increment(); 2996 compressed_frames.Increment();
2988 } 2997 }
2989 2998
2990 } // namespace net 2999 } // 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