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

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

Issue 202113002: Syntactic-only changes to use protocol_version() over spdy_version_ in SpdyFramer. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 9 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 | « no previous file | no next file » | 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 169 matching lines...) Expand 10 before | Expand all | Expand 10 after
180 case SPDY4: 180 case SPDY4:
181 return 8; 181 return 8;
182 } 182 }
183 LOG(DFATAL) << "Unhandled SPDY version."; 183 LOG(DFATAL) << "Unhandled SPDY version.";
184 return 0; 184 return 0;
185 } 185 }
186 186
187 size_t SpdyFramer::GetSynStreamMinimumSize() const { 187 size_t SpdyFramer::GetSynStreamMinimumSize() const {
188 // Size, in bytes, of a SYN_STREAM frame not including the variable-length 188 // Size, in bytes, of a SYN_STREAM frame not including the variable-length
189 // name-value block. 189 // name-value block.
190 if (spdy_version_ < 4) { 190 if (protocol_version() <= SPDY3) {
191 // Calculated as: 191 // Calculated as:
192 // control frame header + 2 * 4 (stream IDs) + 1 (priority) 192 // control frame header + 2 * 4 (stream IDs) + 1 (priority)
193 // + 1 (unused, was credential slot) 193 // + 1 (unused, was credential slot)
194 return GetControlFrameHeaderSize() + 10; 194 return GetControlFrameHeaderSize() + 10;
195 } else { 195 } else {
196 // Calculated as: 196 // Calculated as:
197 // frame prefix + 4 (priority) 197 // frame prefix + 4 (priority)
198 return GetControlFrameHeaderSize() + 4; 198 return GetControlFrameHeaderSize() + 4;
199 } 199 }
200 } 200 }
201 201
202 size_t SpdyFramer::GetSynReplyMinimumSize() const { 202 size_t SpdyFramer::GetSynReplyMinimumSize() const {
203 // Size, in bytes, of a SYN_REPLY frame not including the variable-length 203 // Size, in bytes, of a SYN_REPLY frame not including the variable-length
204 // name-value block. 204 // name-value block.
205 size_t size = GetControlFrameHeaderSize(); 205 size_t size = GetControlFrameHeaderSize();
206 if (spdy_version_ < 4) { 206 if (protocol_version() <= SPDY3) {
207 // Calculated as: 207 // Calculated as:
208 // control frame header + 4 (stream IDs) 208 // control frame header + 4 (stream IDs)
209 size += 4; 209 size += 4;
210 } 210 }
211 211
212 // In SPDY 2, there were 2 unused bytes before payload. 212 // In SPDY 2, there were 2 unused bytes before payload.
213 if (protocol_version() < 3) { 213 if (protocol_version() < SPDY3) {
214 size += 2; 214 size += 2;
215 } 215 }
216 216
217 return size; 217 return size;
218 } 218 }
219 219
220 size_t SpdyFramer::GetRstStreamMinimumSize() const { 220 size_t SpdyFramer::GetRstStreamMinimumSize() const {
221 // Size, in bytes, of a RST_STREAM frame. 221 // Size, in bytes, of a RST_STREAM frame.
222 if (spdy_version_ < 4) { 222 if (protocol_version() <= SPDY3) {
223 // Calculated as: 223 // Calculated as:
224 // control frame header + 4 (stream id) + 4 (status code) 224 // control frame header + 4 (stream id) + 4 (status code)
225 return GetControlFrameHeaderSize() + 8; 225 return GetControlFrameHeaderSize() + 8;
226 } else { 226 } else {
227 // Calculated as: 227 // Calculated as:
228 // frame prefix + 4 (status code) 228 // frame prefix + 4 (status code)
229 return GetControlFrameHeaderSize() + 4; 229 return GetControlFrameHeaderSize() + 4;
230 } 230 }
231 } 231 }
232 232
233 size_t SpdyFramer::GetSettingsMinimumSize() const { 233 size_t SpdyFramer::GetSettingsMinimumSize() const {
234 // Size, in bytes, of a SETTINGS frame not including the IDs and values 234 // Size, in bytes, of a SETTINGS frame not including the IDs and values
235 // from the variable-length value block. Calculated as: 235 // from the variable-length value block. Calculated as:
236 // control frame header + 4 (number of ID/value pairs) 236 // control frame header + 4 (number of ID/value pairs)
237 if (spdy_version_ < 4) { 237 if (protocol_version() <= SPDY3) {
238 return GetControlFrameHeaderSize() + 4; 238 return GetControlFrameHeaderSize() + 4;
239 } else { 239 } else {
240 return GetControlFrameHeaderSize(); 240 return GetControlFrameHeaderSize();
241 } 241 }
242 } 242 }
243 243
244 size_t SpdyFramer::GetPingSize() const { 244 size_t SpdyFramer::GetPingSize() const {
245 // Size, in bytes, of this PING frame. 245 // Size, in bytes, of this PING frame.
246 if (spdy_version_ < 4) { 246 if (protocol_version() <= SPDY3) {
247 // Calculated as: 247 // Calculated as:
248 // control frame header + 4 (id) 248 // control frame header + 4 (id)
249 return GetControlFrameHeaderSize() + 4; 249 return GetControlFrameHeaderSize() + 4;
250 } else { 250 } else {
251 // Calculated as: 251 // Calculated as:
252 // control frame header + 8 (id) 252 // control frame header + 8 (id)
253 return GetControlFrameHeaderSize() + 8; 253 return GetControlFrameHeaderSize() + 8;
254 } 254 }
255 } 255 }
256 256
(...skipping 10 matching lines...) Expand all
267 size += 4; 267 size += 4;
268 } 268 }
269 269
270 return size; 270 return size;
271 } 271 }
272 272
273 size_t SpdyFramer::GetHeadersMinimumSize() const { 273 size_t SpdyFramer::GetHeadersMinimumSize() const {
274 // Size, in bytes, of a HEADERS frame not including the variable-length 274 // Size, in bytes, of a HEADERS frame not including the variable-length
275 // name-value block. 275 // name-value block.
276 size_t size = GetControlFrameHeaderSize(); 276 size_t size = GetControlFrameHeaderSize();
277 if (spdy_version_ < 4) { 277 if (protocol_version() <= SPDY3) {
278 // Calculated as: 278 // Calculated as:
279 // control frame header + 4 (stream IDs) 279 // control frame header + 4 (stream IDs)
280 size += 4; 280 size += 4;
281 } 281 }
282 282
283 // In SPDY 2, there were 2 unused bytes before payload. 283 // In SPDY 2, there were 2 unused bytes before payload.
284 if (protocol_version() < 3) { 284 if (protocol_version() <= SPDY2) {
285 size += 2; 285 size += 2;
286 } 286 }
287 287
288 return size; 288 return size;
289 } 289 }
290 290
291 size_t SpdyFramer::GetWindowUpdateSize() const { 291 size_t SpdyFramer::GetWindowUpdateSize() const {
292 // Size, in bytes, of a WINDOW_UPDATE frame. 292 // Size, in bytes, of a WINDOW_UPDATE frame.
293 if (spdy_version_ < 4) { 293 if (protocol_version() <= SPDY3) {
294 // Calculated as: 294 // Calculated as:
295 // control frame header + 4 (stream id) + 4 (delta) 295 // control frame header + 4 (stream id) + 4 (delta)
296 return GetControlFrameHeaderSize() + 8; 296 return GetControlFrameHeaderSize() + 8;
297 } else { 297 } else {
298 // Calculated as: 298 // Calculated as:
299 // frame prefix + 4 (delta) 299 // frame prefix + 4 (delta)
300 return GetControlFrameHeaderSize() + 4; 300 return GetControlFrameHeaderSize() + 4;
301 } 301 }
302 } 302 }
303 303
(...skipping 15 matching lines...) Expand all
319 // Size, in bytes, of a CONTINUATION frame not including the variable-length 319 // Size, in bytes, of a CONTINUATION frame not including the variable-length
320 // headers fragments. 320 // headers fragments.
321 return GetControlFrameHeaderSize(); 321 return GetControlFrameHeaderSize();
322 } 322 }
323 323
324 size_t SpdyFramer::GetFrameMinimumSize() const { 324 size_t SpdyFramer::GetFrameMinimumSize() const {
325 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 325 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
326 } 326 }
327 327
328 size_t SpdyFramer::GetFrameMaximumSize() const { 328 size_t SpdyFramer::GetFrameMaximumSize() const {
329 if (protocol_version() < 4) { 329 if (protocol_version() <= SPDY3) {
330 // 24-bit length field plus eight-byte frame header. 330 // 24-bit length field plus eight-byte frame header.
331 return ((1<<24) - 1) + 8; 331 return ((1<<24) - 1) + 8;
332 } else { 332 } else {
333 // 14-bit length field. 333 // 14-bit length field.
334 return (1<<14) - 1; 334 return (1<<14) - 1;
335 } 335 }
336 } 336 }
337 337
338 size_t SpdyFramer::GetDataFrameMaximumPayload() const { 338 size_t SpdyFramer::GetDataFrameMaximumPayload() const {
339 return GetFrameMaximumSize() - GetDataFrameMinimumSize(); 339 return GetFrameMaximumSize() - GetDataFrameMinimumSize();
(...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after
524 524
525 case SPDY_SETTINGS_FRAME_PAYLOAD: { 525 case SPDY_SETTINGS_FRAME_PAYLOAD: {
526 int bytes_read = ProcessSettingsFramePayload(data, len); 526 int bytes_read = ProcessSettingsFramePayload(data, len);
527 len -= bytes_read; 527 len -= bytes_read;
528 data += bytes_read; 528 data += bytes_read;
529 break; 529 break;
530 } 530 }
531 531
532 case SPDY_CONTROL_FRAME_HEADER_BLOCK: { 532 case SPDY_CONTROL_FRAME_HEADER_BLOCK: {
533 int bytes_read = ProcessControlFrameHeaderBlock( 533 int bytes_read = ProcessControlFrameHeaderBlock(
534 data, len, spdy_version_ >= 4 ? true : false); 534 data, len, protocol_version() > SPDY3);
535 len -= bytes_read; 535 len -= bytes_read;
536 data += bytes_read; 536 data += bytes_read;
537 break; 537 break;
538 } 538 }
539 539
540 case SPDY_RST_STREAM_FRAME_PAYLOAD: { 540 case SPDY_RST_STREAM_FRAME_PAYLOAD: {
541 size_t bytes_read = ProcessRstStreamFramePayload(data, len); 541 size_t bytes_read = ProcessRstStreamFramePayload(data, len);
542 len -= bytes_read; 542 len -= bytes_read;
543 data += bytes_read; 543 data += bytes_read;
544 break; 544 break;
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after
627 new SpdyFrameReader(current_frame_buffer_.get(), 627 new SpdyFrameReader(current_frame_buffer_.get(),
628 current_frame_buffer_length_)); 628 current_frame_buffer_length_));
629 629
630 uint16 version = 0; 630 uint16 version = 0;
631 bool is_control_frame = false; 631 bool is_control_frame = false;
632 632
633 uint16 control_frame_type_field = DATA; 633 uint16 control_frame_type_field = DATA;
634 // ProcessControlFrameHeader() will set current_frame_type_ to the 634 // ProcessControlFrameHeader() will set current_frame_type_ to the
635 // correct value if this is a valid control frame. 635 // correct value if this is a valid control frame.
636 current_frame_type_ = DATA; 636 current_frame_type_ = DATA;
637 if (protocol_version() < 4) { 637 if (protocol_version() <= SPDY3) {
638 bool successful_read = reader->ReadUInt16(&version); 638 bool successful_read = reader->ReadUInt16(&version);
639 DCHECK(successful_read); 639 DCHECK(successful_read);
640 is_control_frame = (version & kControlFlagMask) != 0; 640 is_control_frame = (version & kControlFlagMask) != 0;
641 version &= ~kControlFlagMask; // Only valid for control frames. 641 version &= ~kControlFlagMask; // Only valid for control frames.
642 642
643 if (is_control_frame) { 643 if (is_control_frame) {
644 // We check control_frame_type_field's validity in 644 // We check control_frame_type_field's validity in
645 // ProcessControlFrameHeader(). 645 // ProcessControlFrameHeader().
646 successful_read = reader->ReadUInt16(&control_frame_type_field); 646 successful_read = reader->ReadUInt16(&control_frame_type_field);
647 } else { 647 } else {
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
718 << " request"; 718 << " request";
719 probable_http_response_ = true; 719 probable_http_response_ = true;
720 } else { 720 } else {
721 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_ 721 LOG(WARNING) << "Unexpectedly large frame. " << display_protocol_
722 << " session is likely corrupt."; 722 << " session is likely corrupt.";
723 } 723 }
724 } 724 }
725 725
726 // if we're here, then we have the common header all received. 726 // if we're here, then we have the common header all received.
727 if (!is_control_frame) { 727 if (!is_control_frame) {
728 if (protocol_version() >= 4) { 728 if (protocol_version() > SPDY3) {
729 // Catch bogus tests sending oversized DATA frames. 729 // Catch bogus tests sending oversized DATA frames.
730 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) 730 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_)
731 << "DATA frame too large for SPDY >= 4."; 731 << "DATA frame too large for SPDY >= 4.";
732 } 732 }
733 733
734 uint8 valid_data_flags = 0; 734 uint8 valid_data_flags = 0;
735 if (protocol_version() >= 4) { 735 if (protocol_version() > SPDY3) {
736 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT | 736 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
737 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH; 737 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH;
738 } else { 738 } else {
739 valid_data_flags = DATA_FLAG_FIN; 739 valid_data_flags = DATA_FLAG_FIN;
740 } 740 }
741 741
742 if (current_frame_flags_ & ~valid_data_flags) { 742 if (current_frame_flags_ & ~valid_data_flags) {
743 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 743 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
744 } else { 744 } else {
745 visitor_->OnDataFrameHeader(current_frame_stream_id_, 745 visitor_->OnDataFrameHeader(current_frame_stream_id_,
746 remaining_data_length_, 746 remaining_data_length_,
747 current_frame_flags_ & DATA_FLAG_FIN); 747 current_frame_flags_ & DATA_FLAG_FIN);
748 if (remaining_data_length_ > 0) { 748 if (remaining_data_length_ > 0) {
749 CHANGE_STATE(SPDY_READ_PADDING_LENGTH); 749 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
750 } else { 750 } else {
751 // Empty data frame. 751 // Empty data frame.
752 if (current_frame_flags_ & DATA_FLAG_FIN) { 752 if (current_frame_flags_ & DATA_FLAG_FIN) {
753 visitor_->OnStreamFrameData( 753 visitor_->OnStreamFrameData(
754 current_frame_stream_id_, NULL, 0, true); 754 current_frame_stream_id_, NULL, 0, true);
755 } 755 }
756 CHANGE_STATE(SPDY_AUTO_RESET); 756 CHANGE_STATE(SPDY_AUTO_RESET);
757 } 757 }
758 } 758 }
759 } else if (version != spdy_version_) { 759 } else if (version != protocol_version()) {
760 // We check version before we check validity: version can never be 760 // We check version before we check validity: version can never be
761 // 'invalid', it can only be unsupported. 761 // 'invalid', it can only be unsupported.
762 DVLOG(1) << "Unsupported SPDY version " << version 762 DVLOG(1) << "Unsupported SPDY version " << version
763 << " (expected " << spdy_version_ << ")"; 763 << " (expected " << protocol_version() << ")";
764 set_error(SPDY_UNSUPPORTED_VERSION); 764 set_error(SPDY_UNSUPPORTED_VERSION);
765 } else { 765 } else {
766 ProcessControlFrameHeader(control_frame_type_field); 766 ProcessControlFrameHeader(control_frame_type_field);
767 } 767 }
768 768
769 return original_len - len; 769 return original_len - len;
770 } 770 }
771 771
772 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) { 772 void SpdyFramer::ProcessControlFrameHeader(uint16 control_frame_type_field) {
773 DCHECK_EQ(SPDY_NO_ERROR, error_code_); 773 DCHECK_EQ(SPDY_NO_ERROR, error_code_);
774 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_); 774 DCHECK_LE(GetControlFrameHeaderSize(), current_frame_buffer_length_);
775 775
776 // Early detection of deprecated frames that we ignore. 776 // Early detection of deprecated frames that we ignore.
777 if (protocol_version() < SPDY4) { 777 if (protocol_version() <= SPDY3) {
778 if (control_frame_type_field == NOOP) { 778 if (control_frame_type_field == NOOP) {
779 current_frame_type_ = NOOP; 779 current_frame_type_ = NOOP;
780 DVLOG(1) << "NOOP control frame found. Ignoring."; 780 DVLOG(1) << "NOOP control frame found. Ignoring.";
781 CHANGE_STATE(SPDY_AUTO_RESET); 781 CHANGE_STATE(SPDY_AUTO_RESET);
782 return; 782 return;
783 } 783 }
784 784
785 if (control_frame_type_field == CREDENTIAL) { 785 if (control_frame_type_field == CREDENTIAL) {
786 current_frame_type_ = CREDENTIAL; 786 current_frame_type_ = CREDENTIAL;
787 DCHECK_EQ(3, protocol_version()); 787 DCHECK_EQ(SPDY3, protocol_version());
788 DVLOG(1) << "CREDENTIAL control frame found. Ignoring."; 788 DVLOG(1) << "CREDENTIAL control frame found. Ignoring.";
789 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 789 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
790 return; 790 return;
791 } 791 }
792 } 792 }
793 793
794 if (!SpdyConstants::IsValidFrameType(protocol_version(), 794 if (!SpdyConstants::IsValidFrameType(protocol_version(),
795 control_frame_type_field)) { 795 control_frame_type_field)) {
796 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field 796 DLOG(WARNING) << "Invalid control frame type " << control_frame_type_field
797 << " (protocol version: " << protocol_version() << ")"; 797 << " (protocol version: " << protocol_version() << ")";
(...skipping 19 matching lines...) Expand all
817 set_error(SPDY_INVALID_CONTROL_FRAME); 817 set_error(SPDY_INVALID_CONTROL_FRAME);
818 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) { 818 } else if (current_frame_flags_ & ~CONTROL_FLAG_FIN) {
819 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 819 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
820 } 820 }
821 break; 821 break;
822 case RST_STREAM: 822 case RST_STREAM:
823 // For SPDY versions < 4, the header has a fixed length. 823 // For SPDY versions < 4, the header has a fixed length.
824 // For SPDY version 4 and up, the RST_STREAM frame may include optional 824 // For SPDY version 4 and up, the RST_STREAM frame may include optional
825 // opaque data, so we only have a lower limit on the frame size. 825 // opaque data, so we only have a lower limit on the frame size.
826 if ((current_frame_length_ != GetRstStreamMinimumSize() && 826 if ((current_frame_length_ != GetRstStreamMinimumSize() &&
827 protocol_version() < 4) || 827 protocol_version() <= SPDY3) ||
828 (current_frame_length_ < GetRstStreamMinimumSize() && 828 (current_frame_length_ < GetRstStreamMinimumSize() &&
829 protocol_version() >= 4)) { 829 protocol_version() > SPDY3)) {
830 set_error(SPDY_INVALID_CONTROL_FRAME); 830 set_error(SPDY_INVALID_CONTROL_FRAME);
831 } else if (current_frame_flags_ != 0) { 831 } else if (current_frame_flags_ != 0) {
832 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 832 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
833 } 833 }
834 break; 834 break;
835 case SETTINGS: 835 case SETTINGS:
836 { 836 {
837 // Make sure that we have an integral number of 8-byte key/value pairs, 837 // Make sure that we have an integral number of 8-byte key/value pairs,
838 // plus a 4-byte length field in SPDY3 and below. 838 // plus a 4-byte length field in SPDY3 and below.
839 size_t values_prefix_size = (protocol_version() < 4 ? 4 : 0); 839 size_t values_prefix_size = (protocol_version() <= SPDY3 ? 4 : 0);
840 // Size of each key/value pair in bytes. 840 // Size of each key/value pair in bytes.
841 size_t setting_size = (protocol_version() < 4 ? 8 : 5); 841 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
842 if (current_frame_length_ < GetSettingsMinimumSize() || 842 if (current_frame_length_ < GetSettingsMinimumSize() ||
843 (current_frame_length_ - GetControlFrameHeaderSize()) 843 (current_frame_length_ - GetControlFrameHeaderSize())
844 % setting_size != values_prefix_size) { 844 % setting_size != values_prefix_size) {
845 DLOG(WARNING) << "Invalid length for SETTINGS frame: " 845 DLOG(WARNING) << "Invalid length for SETTINGS frame: "
846 << current_frame_length_; 846 << current_frame_length_;
847 set_error(SPDY_INVALID_CONTROL_FRAME); 847 set_error(SPDY_INVALID_CONTROL_FRAME);
848 } else if (protocol_version() < 4 && 848 } else if (protocol_version() <= SPDY3 &&
849 current_frame_flags_ & 849 current_frame_flags_ &
850 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) { 850 ~SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS) {
851 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 851 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
852 } else if (protocol_version() >= 4 && 852 } else if (protocol_version() > SPDY3 &&
853 current_frame_flags_ & ~SETTINGS_FLAG_ACK) { 853 current_frame_flags_ & ~SETTINGS_FLAG_ACK) {
854 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 854 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
855 } else if (protocol_version() >= 4 && 855 } else if (protocol_version() > SPDY3 &&
856 current_frame_flags_ & SETTINGS_FLAG_ACK && 856 current_frame_flags_ & SETTINGS_FLAG_ACK &&
857 current_frame_length_ > GetSettingsMinimumSize()) { 857 current_frame_length_ > GetSettingsMinimumSize()) {
858 set_error(SPDY_INVALID_CONTROL_FRAME); 858 set_error(SPDY_INVALID_CONTROL_FRAME);
859 } 859 }
860 break; 860 break;
861 } 861 }
862 case PING: 862 case PING:
863 if (current_frame_length_ != GetPingSize()) { 863 if (current_frame_length_ != GetPingSize()) {
864 set_error(SPDY_INVALID_CONTROL_FRAME); 864 set_error(SPDY_INVALID_CONTROL_FRAME);
865 } else if ((protocol_version() < 4 && current_frame_flags_ != 0) || 865 } else if ((protocol_version() <= SPDY3 && current_frame_flags_ != 0) ||
866 (current_frame_flags_ & ~PING_FLAG_ACK)) { 866 (current_frame_flags_ & ~PING_FLAG_ACK)) {
867 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 867 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
868 } 868 }
869 break; 869 break;
870 case GOAWAY: 870 case GOAWAY:
871 { 871 {
872 // For SPDY version < 4, there are only mandatory fields and the header 872 // For SPDY version < 4, there are only mandatory fields and the header
873 // has a fixed length. For SPDY version >= 4, optional opaque data may 873 // has a fixed length. For SPDY version >= 4, optional opaque data may
874 // be appended to the GOAWAY frame, thus there is only a minimal length 874 // be appended to the GOAWAY frame, thus there is only a minimal length
875 // restriction. 875 // restriction.
876 if ((current_frame_length_ != GetGoAwayMinimumSize() && 876 if ((current_frame_length_ != GetGoAwayMinimumSize() &&
877 protocol_version() < 4) || 877 protocol_version() <= SPDY3) ||
878 (current_frame_length_ < GetGoAwayMinimumSize() && 878 (current_frame_length_ < GetGoAwayMinimumSize() &&
879 protocol_version() >= 4)) { 879 protocol_version() > SPDY3)) {
880 set_error(SPDY_INVALID_CONTROL_FRAME); 880 set_error(SPDY_INVALID_CONTROL_FRAME);
881 } else if (current_frame_flags_ != 0) { 881 } else if (current_frame_flags_ != 0) {
882 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 882 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
883 } 883 }
884 break; 884 break;
885 } 885 }
886 case HEADERS: 886 case HEADERS:
887 { 887 {
888 size_t min_size = GetHeadersMinimumSize(); 888 size_t min_size = GetHeadersMinimumSize();
889 if (spdy_version_ > 3 && 889 if (protocol_version() > SPDY3 &&
890 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) { 890 (current_frame_flags_ & HEADERS_FLAG_PRIORITY)) {
891 min_size += 4; 891 min_size += 4;
892 } 892 }
893 if (current_frame_length_ < min_size) { 893 if (current_frame_length_ < min_size) {
894 set_error(SPDY_INVALID_CONTROL_FRAME); 894 set_error(SPDY_INVALID_CONTROL_FRAME);
895 } else if (spdy_version_ < 4 && 895 } else if (protocol_version() <= SPDY3 &&
896 current_frame_flags_ & ~CONTROL_FLAG_FIN) { 896 current_frame_flags_ & ~CONTROL_FLAG_FIN) {
897 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 897 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
898 } else if (spdy_version_ >= 4 && current_frame_flags_ & 898 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
899 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY | 899 ~(CONTROL_FLAG_FIN | HEADERS_FLAG_PRIORITY |
900 HEADERS_FLAG_END_HEADERS)) { 900 HEADERS_FLAG_END_HEADERS)) {
901 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 901 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
902 } 902 }
903 } 903 }
904 break; 904 break;
905 case WINDOW_UPDATE: 905 case WINDOW_UPDATE:
906 if (current_frame_length_ != GetWindowUpdateSize()) { 906 if (current_frame_length_ != GetWindowUpdateSize()) {
907 set_error(SPDY_INVALID_CONTROL_FRAME); 907 set_error(SPDY_INVALID_CONTROL_FRAME);
908 } else if (current_frame_flags_ != 0) { 908 } else if (current_frame_flags_ != 0) {
909 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 909 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
910 } 910 }
911 break; 911 break;
912 case BLOCKED: 912 case BLOCKED:
913 if (current_frame_length_ != GetBlockedSize()) { 913 if (current_frame_length_ != GetBlockedSize()) {
914 set_error(SPDY_INVALID_CONTROL_FRAME); 914 set_error(SPDY_INVALID_CONTROL_FRAME);
915 } else if (current_frame_flags_ != 0) { 915 } else if (current_frame_flags_ != 0) {
916 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 916 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
917 } 917 }
918 break; 918 break;
919 case PUSH_PROMISE: 919 case PUSH_PROMISE:
920 if (current_frame_length_ < GetPushPromiseMinimumSize()) { 920 if (current_frame_length_ < GetPushPromiseMinimumSize()) {
921 set_error(SPDY_INVALID_CONTROL_FRAME); 921 set_error(SPDY_INVALID_CONTROL_FRAME);
922 } else if (spdy_version_ < 4 && current_frame_flags_ != 0) { 922 } else if (protocol_version() <= SPDY3 && current_frame_flags_ != 0) {
923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 923 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
924 } else if (spdy_version_ >= 4 && current_frame_flags_ & 924 } else if (protocol_version() > SPDY3 && current_frame_flags_ &
925 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) { 925 ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE) {
926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 926 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
927 } 927 }
928 break; 928 break;
929 case CONTINUATION: 929 case CONTINUATION:
930 if (current_frame_length_ < GetContinuationMinimumSize()) { 930 if (current_frame_length_ < GetContinuationMinimumSize()) {
931 set_error(SPDY_INVALID_CONTROL_FRAME); 931 set_error(SPDY_INVALID_CONTROL_FRAME);
932 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) { 932 } else if (current_frame_flags_ & ~HEADERS_FLAG_END_HEADERS) {
933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS); 933 set_error(SPDY_INVALID_CONTROL_FRAME_FLAGS);
934 } 934 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
976 break; 976 break;
977 case SYN_REPLY: 977 case SYN_REPLY:
978 syn_frame_processed_ = true; 978 syn_frame_processed_ = true;
979 frame_size_without_variable_data = GetSynReplyMinimumSize(); 979 frame_size_without_variable_data = GetSynReplyMinimumSize();
980 break; 980 break;
981 case SETTINGS: 981 case SETTINGS:
982 frame_size_without_variable_data = GetSettingsMinimumSize(); 982 frame_size_without_variable_data = GetSettingsMinimumSize();
983 break; 983 break;
984 case HEADERS: 984 case HEADERS:
985 frame_size_without_variable_data = GetHeadersMinimumSize(); 985 frame_size_without_variable_data = GetHeadersMinimumSize();
986 if (spdy_version_ > 3 && current_frame_flags_ & HEADERS_FLAG_PRIORITY) { 986 if (protocol_version() > SPDY3 &&
987 current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
987 frame_size_without_variable_data += 4; // priority 988 frame_size_without_variable_data += 4; // priority
988 } 989 }
989 break; 990 break;
990 case PUSH_PROMISE: 991 case PUSH_PROMISE:
991 frame_size_without_variable_data = GetPushPromiseMinimumSize(); 992 frame_size_without_variable_data = GetPushPromiseMinimumSize();
992 break; 993 break;
993 case CONTINUATION: 994 case CONTINUATION:
994 frame_size_without_variable_data = GetContinuationMinimumSize(); 995 frame_size_without_variable_data = GetContinuationMinimumSize();
995 break; 996 break;
996 default: 997 default:
(...skipping 264 matching lines...) Expand 10 before | Expand all | Expand 10 after
1261 } 1262 }
1262 1263
1263 if (remaining_control_header_ == 0) { 1264 if (remaining_control_header_ == 0) {
1264 SpdyFrameReader reader(current_frame_buffer_.get(), 1265 SpdyFrameReader reader(current_frame_buffer_.get(),
1265 current_frame_buffer_length_); 1266 current_frame_buffer_length_);
1266 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1267 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1267 1268
1268 switch (current_frame_type_) { 1269 switch (current_frame_type_) {
1269 case SYN_STREAM: 1270 case SYN_STREAM:
1270 { 1271 {
1271 DCHECK_GT(4, spdy_version_); 1272 DCHECK_GE(SPDY3, protocol_version());
1272 bool successful_read = true; 1273 bool successful_read = true;
1273 if (spdy_version_ < 4) { 1274 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1274 successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1275 DCHECK(successful_read);
1275 DCHECK(successful_read);
1276 }
1277 if (current_frame_stream_id_ == 0) { 1276 if (current_frame_stream_id_ == 0) {
1278 set_error(SPDY_INVALID_CONTROL_FRAME); 1277 set_error(SPDY_INVALID_CONTROL_FRAME);
1279 break; 1278 break;
1280 } 1279 }
1281 1280
1282 SpdyStreamId associated_to_stream_id = kInvalidStream; 1281 SpdyStreamId associated_to_stream_id = kInvalidStream;
1283 successful_read = reader.ReadUInt31(&associated_to_stream_id); 1282 successful_read = reader.ReadUInt31(&associated_to_stream_id);
1284 DCHECK(successful_read); 1283 DCHECK(successful_read);
1285 1284
1286 SpdyPriority priority = 0; 1285 SpdyPriority priority = 0;
1287 successful_read = reader.ReadUInt8(&priority); 1286 successful_read = reader.ReadUInt8(&priority);
1288 DCHECK(successful_read); 1287 DCHECK(successful_read);
1289 if (protocol_version() < 3) { 1288 if (protocol_version() <= SPDY2) {
1290 priority = priority >> 6; 1289 priority = priority >> 6;
1291 } else { 1290 } else {
1292 priority = priority >> 5; 1291 priority = priority >> 5;
1293 } 1292 }
1294 1293
1295 // Seek past unused byte; used to be credential slot in SPDY 3. 1294 // Seek past unused byte; used to be credential slot in SPDY 3.
1296 reader.Seek(1); 1295 reader.Seek(1);
1297 1296
1298 DCHECK(reader.IsDoneReading()); 1297 DCHECK(reader.IsDoneReading());
1299 if (debug_visitor_) { 1298 if (debug_visitor_) {
1300 debug_visitor_->OnReceiveCompressedFrame( 1299 debug_visitor_->OnReceiveCompressedFrame(
1301 current_frame_stream_id_, 1300 current_frame_stream_id_,
1302 current_frame_type_, 1301 current_frame_type_,
1303 current_frame_length_); 1302 current_frame_length_);
1304 } 1303 }
1305 visitor_->OnSynStream( 1304 visitor_->OnSynStream(
1306 current_frame_stream_id_, 1305 current_frame_stream_id_,
1307 associated_to_stream_id, 1306 associated_to_stream_id,
1308 priority, 1307 priority,
1309 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1308 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1310 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0); 1309 (current_frame_flags_ & CONTROL_FLAG_UNIDIRECTIONAL) != 0);
1311 } 1310 }
1312 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1311 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1313 break; 1312 break;
1314 case SETTINGS: 1313 case SETTINGS:
1315 if (spdy_version_ >= 4 && current_frame_flags_ & SETTINGS_FLAG_ACK) { 1314 if (protocol_version() > SPDY3 &&
1315 current_frame_flags_ & SETTINGS_FLAG_ACK) {
1316 visitor_->OnSettingsAck(); 1316 visitor_->OnSettingsAck();
1317 CHANGE_STATE(SPDY_AUTO_RESET); 1317 CHANGE_STATE(SPDY_AUTO_RESET);
1318 } else { 1318 } else {
1319 visitor_->OnSettings(current_frame_flags_ & 1319 visitor_->OnSettings(current_frame_flags_ &
1320 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS); 1320 SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS);
1321 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD); 1321 CHANGE_STATE(SPDY_SETTINGS_FRAME_PAYLOAD);
1322 } 1322 }
1323 break; 1323 break;
1324 case SYN_REPLY: 1324 case SYN_REPLY:
1325 case HEADERS: 1325 case HEADERS:
1326 // SYN_REPLY and HEADERS are the same, save for the visitor call. 1326 // SYN_REPLY and HEADERS are the same, save for the visitor call.
1327 { 1327 {
1328 if (spdy_version_ > 3) { 1328 if (protocol_version() > SPDY3) {
1329 DCHECK_EQ(HEADERS, current_frame_type_); 1329 DCHECK_EQ(HEADERS, current_frame_type_);
1330 } 1330 }
1331 bool successful_read = true; 1331 bool successful_read = true;
1332 if (spdy_version_ < 4) { 1332 if (protocol_version() <= SPDY3) {
1333 successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1333 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1334 DCHECK(successful_read); 1334 DCHECK(successful_read);
1335 } 1335 }
1336 if (current_frame_stream_id_ == 0) { 1336 if (current_frame_stream_id_ == 0) {
1337 set_error(SPDY_INVALID_CONTROL_FRAME); 1337 set_error(SPDY_INVALID_CONTROL_FRAME);
1338 break; 1338 break;
1339 } 1339 }
1340 if (protocol_version() < 3) { 1340 if (protocol_version() <= SPDY2) {
1341 // SPDY 2 had two unused bytes here. Seek past them. 1341 // SPDY 2 had two unused bytes here. Seek past them.
1342 reader.Seek(2); 1342 reader.Seek(2);
1343 } 1343 }
1344 if (spdy_version_ > 3 && 1344 if (protocol_version() > SPDY3 &&
1345 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && 1345 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
1346 current_frame_type_ == HEADERS) { 1346 current_frame_type_ == HEADERS) {
1347 expect_continuation_ = current_frame_stream_id_; 1347 expect_continuation_ = current_frame_stream_id_;
1348 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; 1348 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
1349 } 1349 }
1350 const bool has_priority = 1350 const bool has_priority =
1351 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; 1351 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
1352 uint32 priority = 0; 1352 uint32 priority = 0;
1353 if (protocol_version() > 3 && has_priority) { 1353 if (protocol_version() > SPDY3 && has_priority) {
1354 successful_read = reader.ReadUInt31(&priority); 1354 successful_read = reader.ReadUInt31(&priority);
1355 DCHECK(successful_read); 1355 DCHECK(successful_read);
1356 } 1356 }
1357 DCHECK(reader.IsDoneReading()); 1357 DCHECK(reader.IsDoneReading());
1358 if (debug_visitor_) { 1358 if (debug_visitor_) {
1359 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. 1359 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
1360 SpdyFrameType reported_type = current_frame_type_; 1360 SpdyFrameType reported_type = current_frame_type_;
1361 if (protocol_version() > 3 && has_priority) { 1361 if (protocol_version() > SPDY3 && has_priority) {
1362 reported_type = SYN_STREAM; 1362 reported_type = SYN_STREAM;
1363 } 1363 }
1364 debug_visitor_->OnReceiveCompressedFrame( 1364 debug_visitor_->OnReceiveCompressedFrame(
1365 current_frame_stream_id_, 1365 current_frame_stream_id_,
1366 reported_type, 1366 reported_type,
1367 current_frame_length_); 1367 current_frame_length_);
1368 } 1368 }
1369 if (current_frame_type_ == SYN_REPLY) { 1369 if (current_frame_type_ == SYN_REPLY) {
1370 visitor_->OnSynReply( 1370 visitor_->OnSynReply(
1371 current_frame_stream_id_, 1371 current_frame_stream_id_,
1372 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0); 1372 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0);
1373 } else if (spdy_version_ > 3 && 1373 } else if (protocol_version() > SPDY3 &&
1374 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { 1374 current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
1375 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes 1375 // SPDY 4+ is missing SYN_STREAM. Simulate it so that API changes
1376 // can be made independent of wire changes. 1376 // can be made independent of wire changes.
1377 visitor_->OnSynStream( 1377 visitor_->OnSynStream(
1378 current_frame_stream_id_, 1378 current_frame_stream_id_,
1379 0, // associated_to_stream_id 1379 0, // associated_to_stream_id
1380 priority, 1380 priority,
1381 current_frame_flags_ & CONTROL_FLAG_FIN, 1381 current_frame_flags_ & CONTROL_FLAG_FIN,
1382 false); // unidirectional 1382 false); // unidirectional
1383 } else { 1383 } else {
1384 visitor_->OnHeaders( 1384 visitor_->OnHeaders(
1385 current_frame_stream_id_, 1385 current_frame_stream_id_,
1386 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0, 1386 (current_frame_flags_ & CONTROL_FLAG_FIN) != 0,
1387 expect_continuation_ == 0); 1387 expect_continuation_ == 0);
1388 } 1388 }
1389 } 1389 }
1390 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK); 1390 CHANGE_STATE(SPDY_CONTROL_FRAME_HEADER_BLOCK);
1391 break; 1391 break;
1392 case PUSH_PROMISE: 1392 case PUSH_PROMISE:
1393 { 1393 {
1394 DCHECK_LE(4, protocol_version()); 1394 DCHECK_LT(SPDY3, protocol_version());
1395 if (current_frame_stream_id_ == 0) { 1395 if (current_frame_stream_id_ == 0) {
1396 set_error(SPDY_INVALID_CONTROL_FRAME); 1396 set_error(SPDY_INVALID_CONTROL_FRAME);
1397 break; 1397 break;
1398 } 1398 }
1399 SpdyStreamId promised_stream_id = kInvalidStream; 1399 SpdyStreamId promised_stream_id = kInvalidStream;
1400 bool successful_read = reader.ReadUInt31(&promised_stream_id); 1400 bool successful_read = reader.ReadUInt31(&promised_stream_id);
1401 DCHECK(successful_read); 1401 DCHECK(successful_read);
1402 DCHECK(reader.IsDoneReading()); 1402 DCHECK(reader.IsDoneReading());
1403 if (promised_stream_id == 0) { 1403 if (promised_stream_id == 0) {
1404 set_error(SPDY_INVALID_CONTROL_FRAME); 1404 set_error(SPDY_INVALID_CONTROL_FRAME);
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
1473 size_t process_bytes = std::min(data_len, remaining_data_length_); 1473 size_t process_bytes = std::min(data_len, remaining_data_length_);
1474 if (is_hpack_header_block) { 1474 if (is_hpack_header_block) {
1475 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_, 1475 if (!hpack_decoder_.HandleControlFrameHeadersData(current_frame_stream_id_,
1476 data, 1476 data,
1477 process_bytes)) { 1477 process_bytes)) {
1478 // TODO(jgraettinger): Finer-grained HPACK error codes. 1478 // TODO(jgraettinger): Finer-grained HPACK error codes.
1479 set_error(SPDY_DECOMPRESS_FAILURE); 1479 set_error(SPDY_DECOMPRESS_FAILURE);
1480 processed_successfully = false; 1480 processed_successfully = false;
1481 } 1481 }
1482 } else if (process_bytes > 0) { 1482 } else if (process_bytes > 0) {
1483 if (enable_compression_ && spdy_version_ < 4) { 1483 if (enable_compression_ && protocol_version() <= SPDY3) {
1484 processed_successfully = IncrementallyDecompressControlFrameHeaderData( 1484 processed_successfully = IncrementallyDecompressControlFrameHeaderData(
1485 current_frame_stream_id_, data, process_bytes); 1485 current_frame_stream_id_, data, process_bytes);
1486 } else { 1486 } else {
1487 processed_successfully = IncrementallyDeliverControlFrameHeaderData( 1487 processed_successfully = IncrementallyDeliverControlFrameHeaderData(
1488 current_frame_stream_id_, data, process_bytes); 1488 current_frame_stream_id_, data, process_bytes);
1489 } 1489 }
1490 } 1490 }
1491 remaining_data_length_ -= process_bytes; 1491 remaining_data_length_ -= process_bytes;
1492 1492
1493 // Handle the case that there is no futher data in this frame. 1493 // Handle the case that there is no futher data in this frame.
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1530 return process_bytes; 1530 return process_bytes;
1531 } 1531 }
1532 1532
1533 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, 1533 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
1534 size_t data_len) { 1534 size_t data_len) {
1535 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); 1535 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
1536 DCHECK_EQ(SETTINGS, current_frame_type_); 1536 DCHECK_EQ(SETTINGS, current_frame_type_);
1537 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); 1537 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
1538 size_t processed_bytes = 0; 1538 size_t processed_bytes = 0;
1539 1539
1540 size_t setting_size = spdy_version_ < 4 ? 8 : 5; 1540 size_t setting_size = protocol_version() <= SPDY3 ? 8 : 5;
1541 1541
1542 // Loop over our incoming data. 1542 // Loop over our incoming data.
1543 while (unprocessed_bytes > 0) { 1543 while (unprocessed_bytes > 0) {
1544 // Process up to one setting at a time. 1544 // Process up to one setting at a time.
1545 size_t processing = std::min( 1545 size_t processing = std::min(
1546 unprocessed_bytes, 1546 unprocessed_bytes,
1547 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len)); 1547 static_cast<size_t>(setting_size - settings_scratch_.setting_buf_len));
1548 1548
1549 // Check if we have a complete setting in our input. 1549 // Check if we have a complete setting in our input.
1550 if (processing == setting_size) { 1550 if (processing == setting_size) {
(...skipping 29 matching lines...) Expand all
1580 remaining_data_length_ -= processed_bytes; 1580 remaining_data_length_ -= processed_bytes;
1581 if (remaining_data_length_ == 0) { 1581 if (remaining_data_length_ == 0) {
1582 visitor_->OnSettingsEnd(); 1582 visitor_->OnSettingsEnd();
1583 CHANGE_STATE(SPDY_AUTO_RESET); 1583 CHANGE_STATE(SPDY_AUTO_RESET);
1584 } 1584 }
1585 1585
1586 return processed_bytes; 1586 return processed_bytes;
1587 } 1587 }
1588 1588
1589 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() { 1589 void SpdyFramer::DeliverHpackBlockAsSpdy3Block() {
1590 DCHECK_GE(spdy_version_, SPDY4); 1590 DCHECK_LT(SPDY3, protocol_version());
1591 DCHECK_EQ(remaining_data_length_, 0u); 1591 DCHECK_EQ(0u, remaining_data_length_);
1592 1592
1593 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block(); 1593 const SpdyNameValueBlock& block = hpack_decoder_.decoded_block();
1594 if (block.empty()) { 1594 if (block.empty()) {
1595 // Special-case this to make tests happy. 1595 // Special-case this to make tests happy.
1596 ProcessControlFrameHeaderBlock(NULL, 0, false); 1596 ProcessControlFrameHeaderBlock(NULL, 0, false);
1597 return; 1597 return;
1598 } 1598 }
1599 SpdyFrameBuilder builder( 1599 SpdyFrameBuilder builder(
1600 GetSerializedLength(protocol_version(), &block)); 1600 GetSerializedLength(protocol_version(), &block));
1601 1601
1602 SerializeNameValueBlockWithoutCompression(&builder, block); 1602 SerializeNameValueBlockWithoutCompression(&builder, block);
1603 scoped_ptr<SpdyFrame> frame(builder.take()); 1603 scoped_ptr<SpdyFrame> frame(builder.take());
1604 1604
1605 remaining_data_length_ = frame->size(); 1605 remaining_data_length_ = frame->size();
1606 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false); 1606 ProcessControlFrameHeaderBlock(frame->data(), frame->size(), false);
1607 } 1607 }
1608 1608
1609 bool SpdyFramer::ProcessSetting(const char* data) { 1609 bool SpdyFramer::ProcessSetting(const char* data) {
1610 SpdySettingsIds id; 1610 SpdySettingsIds id;
1611 uint8 flags = 0; 1611 uint8 flags = 0;
1612 uint32 value; 1612 uint32 value;
1613 1613
1614 // Extract fields. 1614 // Extract fields.
1615 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id. 1615 // Maintain behavior of old SPDY 2 bug with byte ordering of flags/id.
1616 if (spdy_version_ < 4) { 1616 if (protocol_version() <= SPDY3) {
1617 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data)); 1617 const uint32 id_and_flags_wire = *(reinterpret_cast<const uint32*>(data));
1618 SettingsFlagsAndId id_and_flags = 1618 SettingsFlagsAndId id_and_flags =
1619 SettingsFlagsAndId::FromWireFormat(spdy_version_, id_and_flags_wire); 1619 SettingsFlagsAndId::FromWireFormat(protocol_version(), id_and_flags_wire);
1620 id = static_cast<SpdySettingsIds>(id_and_flags.id()); 1620 id = static_cast<SpdySettingsIds>(id_and_flags.id());
1621 flags = id_and_flags.flags(); 1621 flags = id_and_flags.flags();
1622 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4))); 1622 value = ntohl(*(reinterpret_cast<const uint32*>(data + 4)));
1623 } else { 1623 } else {
1624 id = static_cast<SpdySettingsIds>(*(reinterpret_cast<const uint8*>(data))); 1624 id = static_cast<SpdySettingsIds>(*(reinterpret_cast<const uint8*>(data)));
1625 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1))); 1625 value = ntohl(*(reinterpret_cast<const uint32*>(data + 1)));
1626 } 1626 }
1627 1627
1628 // Validate id. 1628 // Validate id.
1629 switch (id) { 1629 switch (id) {
1630 case SETTINGS_UPLOAD_BANDWIDTH: 1630 case SETTINGS_UPLOAD_BANDWIDTH:
1631 case SETTINGS_DOWNLOAD_BANDWIDTH: 1631 case SETTINGS_DOWNLOAD_BANDWIDTH:
1632 case SETTINGS_ROUND_TRIP_TIME: 1632 case SETTINGS_ROUND_TRIP_TIME:
1633 case SETTINGS_MAX_CONCURRENT_STREAMS: 1633 case SETTINGS_MAX_CONCURRENT_STREAMS:
1634 case SETTINGS_CURRENT_CWND: 1634 case SETTINGS_CURRENT_CWND:
1635 case SETTINGS_DOWNLOAD_RETRANS_RATE: 1635 case SETTINGS_DOWNLOAD_RETRANS_RATE:
1636 case SETTINGS_INITIAL_WINDOW_SIZE: 1636 case SETTINGS_INITIAL_WINDOW_SIZE:
1637 // Valid values. 1637 // Valid values.
1638 break; 1638 break;
1639 default: 1639 default:
1640 DLOG(WARNING) << "Unknown SETTINGS ID: " << id; 1640 DLOG(WARNING) << "Unknown SETTINGS ID: " << id;
1641 return false; 1641 return false;
1642 } 1642 }
1643 1643
1644 if (spdy_version_ < 4) { 1644 if (protocol_version() <= SPDY3) {
1645 // Detect duplicates. 1645 // Detect duplicates.
1646 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) { 1646 if (static_cast<uint32>(id) <= settings_scratch_.last_setting_id) {
1647 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id 1647 DLOG(WARNING) << "Duplicate entry or invalid ordering for id " << id
1648 << " in " << display_protocol_ << " SETTINGS frame " 1648 << " in " << display_protocol_ << " SETTINGS frame "
1649 << "(last setting id was " 1649 << "(last setting id was "
1650 << settings_scratch_.last_setting_id << ")."; 1650 << settings_scratch_.last_setting_id << ").";
1651 return false; 1651 return false;
1652 } 1652 }
1653 settings_scratch_.last_setting_id = id; 1653 settings_scratch_.last_setting_id = id;
1654 1654
(...skipping 18 matching lines...) Expand all
1673 remaining_data_length_ -= bytes_read; 1673 remaining_data_length_ -= bytes_read;
1674 if (remaining_data_length_ == 0) { 1674 if (remaining_data_length_ == 0) {
1675 SpdyFrameReader reader(current_frame_buffer_.get(), 1675 SpdyFrameReader reader(current_frame_buffer_.get(),
1676 current_frame_buffer_length_); 1676 current_frame_buffer_length_);
1677 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header. 1677 reader.Seek(GetControlFrameHeaderSize()); // Skip frame header.
1678 1678
1679 // Use frame-specific handlers. 1679 // Use frame-specific handlers.
1680 switch (current_frame_type_) { 1680 switch (current_frame_type_) {
1681 case PING: { 1681 case PING: {
1682 SpdyPingId id = 0; 1682 SpdyPingId id = 0;
1683 bool is_ack = 1683 bool is_ack = protocol_version() > SPDY3 &&
1684 spdy_version_ >= 4 && (current_frame_flags_ & PING_FLAG_ACK); 1684 (current_frame_flags_ & PING_FLAG_ACK);
1685 bool successful_read = true; 1685 bool successful_read = true;
1686 if (spdy_version_ < 4) { 1686 if (protocol_version() <= SPDY3) {
1687 uint32 id32 = 0; 1687 uint32 id32 = 0;
1688 successful_read = reader.ReadUInt32(&id32); 1688 successful_read = reader.ReadUInt32(&id32);
1689 id = id32; 1689 id = id32;
1690 } else { 1690 } else {
1691 successful_read = reader.ReadUInt64(&id); 1691 successful_read = reader.ReadUInt64(&id);
1692 } 1692 }
1693 DCHECK(successful_read); 1693 DCHECK(successful_read);
1694 DCHECK(reader.IsDoneReading()); 1694 DCHECK(reader.IsDoneReading());
1695 visitor_->OnPing(id, is_ack); 1695 visitor_->OnPing(id, is_ack);
1696 } 1696 }
1697 break; 1697 break;
1698 case WINDOW_UPDATE: { 1698 case WINDOW_UPDATE: {
1699 uint32 delta_window_size = 0; 1699 uint32 delta_window_size = 0;
1700 bool successful_read = true; 1700 bool successful_read = true;
1701 if (spdy_version_ < 4) { 1701 if (protocol_version() <= SPDY3) {
1702 successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1702 successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1703 DCHECK(successful_read); 1703 DCHECK(successful_read);
1704 } 1704 }
1705 successful_read = reader.ReadUInt32(&delta_window_size); 1705 successful_read = reader.ReadUInt32(&delta_window_size);
1706 DCHECK(successful_read); 1706 DCHECK(successful_read);
1707 DCHECK(reader.IsDoneReading()); 1707 DCHECK(reader.IsDoneReading());
1708 visitor_->OnWindowUpdate(current_frame_stream_id_, 1708 visitor_->OnWindowUpdate(current_frame_stream_id_,
1709 delta_window_size); 1709 delta_window_size);
1710 } 1710 }
1711 break; 1711 break;
1712 case BLOCKED: { 1712 case BLOCKED: {
1713 DCHECK_LE(4, protocol_version()); 1713 DCHECK_LT(SPDY3, protocol_version());
1714 DCHECK(reader.IsDoneReading()); 1714 DCHECK(reader.IsDoneReading());
1715 visitor_->OnBlocked(current_frame_stream_id_); 1715 visitor_->OnBlocked(current_frame_stream_id_);
1716 } 1716 }
1717 break; 1717 break;
1718 default: 1718 default:
1719 // Unreachable. 1719 // Unreachable.
1720 LOG(FATAL) << "Unhandled control frame " << current_frame_type_; 1720 LOG(FATAL) << "Unhandled control frame " << current_frame_type_;
1721 } 1721 }
1722 1722
1723 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD); 1723 CHANGE_STATE(SPDY_IGNORE_REMAINING_PAYLOAD);
(...skipping 23 matching lines...) Expand all
1747 if (current_frame_buffer_length_ == header_size) { 1747 if (current_frame_buffer_length_ == header_size) {
1748 // Parse out the last good stream id. 1748 // Parse out the last good stream id.
1749 SpdyFrameReader reader(current_frame_buffer_.get(), 1749 SpdyFrameReader reader(current_frame_buffer_.get(),
1750 current_frame_buffer_length_); 1750 current_frame_buffer_length_);
1751 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1751 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1752 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1752 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1753 DCHECK(successful_read); 1753 DCHECK(successful_read);
1754 1754
1755 // In SPDYv3 and up, frames also specify a status code - parse it out. 1755 // In SPDYv3 and up, frames also specify a status code - parse it out.
1756 SpdyGoAwayStatus status = GOAWAY_OK; 1756 SpdyGoAwayStatus status = GOAWAY_OK;
1757 if (spdy_version_ >= 3) { 1757 if (protocol_version() >= SPDY3) {
1758 uint32 status_raw = GOAWAY_OK; 1758 uint32 status_raw = GOAWAY_OK;
1759 successful_read = reader.ReadUInt32(&status_raw); 1759 successful_read = reader.ReadUInt32(&status_raw);
1760 DCHECK(successful_read); 1760 DCHECK(successful_read);
1761 // We've read an unsigned integer, so it's enough to only check 1761 // We've read an unsigned integer, so it's enough to only check
1762 // upper bound to ensure the value is in valid range. 1762 // upper bound to ensure the value is in valid range.
1763 if (status_raw < GOAWAY_NUM_STATUS_CODES) { 1763 if (status_raw < GOAWAY_NUM_STATUS_CODES) {
1764 status = static_cast<SpdyGoAwayStatus>(status_raw); 1764 status = static_cast<SpdyGoAwayStatus>(status_raw);
1765 } else { 1765 } else {
1766 // TODO(hkhalil): Probably best to OnError here, depending on 1766 // TODO(hkhalil): Probably best to OnError here, depending on
1767 // our interpretation of the spec. Keeping with existing liberal 1767 // our interpretation of the spec. Keeping with existing liberal
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 if (!already_parsed_header) { 1808 if (!already_parsed_header) {
1809 // Buffer the new RST_STREAM header bytes we got. 1809 // Buffer the new RST_STREAM header bytes we got.
1810 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes); 1810 UpdateCurrentFrameBuffer(&data, &len, unread_header_bytes);
1811 1811
1812 // Do we have enough to parse the constant size RST_STREAM header? 1812 // Do we have enough to parse the constant size RST_STREAM header?
1813 if (current_frame_buffer_length_ == header_size) { 1813 if (current_frame_buffer_length_ == header_size) {
1814 // Parse out the last good stream id. 1814 // Parse out the last good stream id.
1815 SpdyFrameReader reader(current_frame_buffer_.get(), 1815 SpdyFrameReader reader(current_frame_buffer_.get(),
1816 current_frame_buffer_length_); 1816 current_frame_buffer_length_);
1817 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header. 1817 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
1818 if (protocol_version() < 4) { 1818 if (protocol_version() <= SPDY3) {
1819 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_); 1819 bool successful_read = reader.ReadUInt31(&current_frame_stream_id_);
1820 DCHECK(successful_read); 1820 DCHECK(successful_read);
1821 } 1821 }
1822 1822
1823 SpdyRstStreamStatus status = RST_STREAM_INVALID; 1823 SpdyRstStreamStatus status = RST_STREAM_INVALID;
1824 uint32 status_raw = status; 1824 uint32 status_raw = status;
1825 bool successful_read = reader.ReadUInt32(&status_raw); 1825 bool successful_read = reader.ReadUInt32(&status_raw);
1826 DCHECK(successful_read); 1826 DCHECK(successful_read);
1827 // We've read an unsigned integer, so it's enough to only check 1827 // We've read an unsigned integer, so it's enough to only check
1828 // upper bound to ensure the value is in valid range. 1828 // upper bound to ensure the value is in valid range.
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
1960 return original_len - len; 1960 return original_len - len;
1961 } 1961 }
1962 1962
1963 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 1963 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
1964 size_t header_length, 1964 size_t header_length,
1965 SpdyHeaderBlock* block) const { 1965 SpdyHeaderBlock* block) const {
1966 SpdyFrameReader reader(header_data, header_length); 1966 SpdyFrameReader reader(header_data, header_length);
1967 1967
1968 // Read number of headers. 1968 // Read number of headers.
1969 uint32 num_headers; 1969 uint32 num_headers;
1970 if (spdy_version_ < 3) { 1970 if (protocol_version() <= SPDY2) {
1971 uint16 temp; 1971 uint16 temp;
1972 if (!reader.ReadUInt16(&temp)) { 1972 if (!reader.ReadUInt16(&temp)) {
1973 DVLOG(1) << "Unable to read number of headers."; 1973 DVLOG(1) << "Unable to read number of headers.";
1974 return 0; 1974 return 0;
1975 } 1975 }
1976 num_headers = temp; 1976 num_headers = temp;
1977 } else { 1977 } else {
1978 if (!reader.ReadUInt32(&num_headers)) { 1978 if (!reader.ReadUInt32(&num_headers)) {
1979 DVLOG(1) << "Unable to read number of headers."; 1979 DVLOG(1) << "Unable to read number of headers.";
1980 return 0; 1980 return 0;
1981 } 1981 }
1982 } 1982 }
1983 1983
1984 // Read each header. 1984 // Read each header.
1985 for (uint32 index = 0; index < num_headers; ++index) { 1985 for (uint32 index = 0; index < num_headers; ++index) {
1986 base::StringPiece temp; 1986 base::StringPiece temp;
1987 1987
1988 // Read header name. 1988 // Read header name.
1989 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1989 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
1990 : !reader.ReadStringPiece32(&temp)) { 1990 : !reader.ReadStringPiece32(&temp)) {
1991 DVLOG(1) << "Unable to read header name (" << index + 1 << " of " 1991 DVLOG(1) << "Unable to read header name (" << index + 1 << " of "
1992 << num_headers << ")."; 1992 << num_headers << ").";
1993 return 0; 1993 return 0;
1994 } 1994 }
1995 std::string name = temp.as_string(); 1995 std::string name = temp.as_string();
1996 1996
1997 // Read header value. 1997 // Read header value.
1998 if ((spdy_version_ < 3) ? !reader.ReadStringPiece16(&temp) 1998 if ((protocol_version() <= SPDY2) ? !reader.ReadStringPiece16(&temp)
1999 : !reader.ReadStringPiece32(&temp)) { 1999 : !reader.ReadStringPiece32(&temp)) {
2000 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " 2000 DVLOG(1) << "Unable to read header value (" << index + 1 << " of "
2001 << num_headers << ")."; 2001 << num_headers << ").";
2002 return 0; 2002 return 0;
2003 } 2003 }
2004 std::string value = temp.as_string(); 2004 std::string value = temp.as_string();
2005 2005
2006 // Ensure no duplicates. 2006 // Ensure no duplicates.
2007 if (block->find(name) != block->end()) { 2007 if (block->find(name) != block->end()) {
2008 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " 2008 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of "
2009 << num_headers << ")."; 2009 << num_headers << ").";
2010 return 0; 2010 return 0;
2011 } 2011 }
2012 2012
2013 // Store header. 2013 // Store header.
2014 (*block)[name] = value; 2014 (*block)[name] = value;
2015 } 2015 }
2016 return reader.GetBytesConsumed(); 2016 return reader.GetBytesConsumed();
2017 } 2017 }
2018 2018
2019 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& datair) const { 2019 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& datair) const {
2020 uint8 flags = DATA_FLAG_NONE; 2020 uint8 flags = DATA_FLAG_NONE;
2021 if (datair.fin()) { 2021 if (datair.fin()) {
2022 flags = DATA_FLAG_FIN; 2022 flags = DATA_FLAG_FIN;
2023 } 2023 }
2024 2024
2025 if (protocol_version() >= 4) { 2025 if (protocol_version() > SPDY3) {
2026 int num_padding_fields = 0; 2026 int num_padding_fields = 0;
2027 if (datair.pad_low()) { 2027 if (datair.pad_low()) {
2028 flags |= DATA_FLAG_PAD_LOW; 2028 flags |= DATA_FLAG_PAD_LOW;
2029 ++num_padding_fields; 2029 ++num_padding_fields;
2030 } 2030 }
2031 if (datair.pad_high()) { 2031 if (datair.pad_high()) {
2032 flags |= DATA_FLAG_PAD_HIGH; 2032 flags |= DATA_FLAG_PAD_HIGH;
2033 ++num_padding_fields; 2033 ++num_padding_fields;
2034 } 2034 }
2035 2035
(...skipping 26 matching lines...) Expand all
2062 } 2062 }
2063 2063
2064 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( 2064 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader(
2065 const SpdyDataIR& data) const { 2065 const SpdyDataIR& data) const {
2066 const size_t kSize = GetDataFrameMinimumSize(); 2066 const size_t kSize = GetDataFrameMinimumSize();
2067 2067
2068 uint8 flags = DATA_FLAG_NONE; 2068 uint8 flags = DATA_FLAG_NONE;
2069 if (data.fin()) { 2069 if (data.fin()) {
2070 flags = DATA_FLAG_FIN; 2070 flags = DATA_FLAG_FIN;
2071 } 2071 }
2072 if (protocol_version() >= 4) { 2072 if (protocol_version() > SPDY3) {
2073 if (data.pad_low()) { 2073 if (data.pad_low()) {
2074 flags |= DATA_FLAG_PAD_LOW; 2074 flags |= DATA_FLAG_PAD_LOW;
2075 } 2075 }
2076 if (data.pad_high()) { 2076 if (data.pad_high()) {
2077 flags |= DATA_FLAG_PAD_HIGH; 2077 flags |= DATA_FLAG_PAD_HIGH;
2078 } 2078 }
2079 } 2079 }
2080 2080
2081 SpdyFrameBuilder builder(kSize); 2081 SpdyFrameBuilder builder(kSize);
2082 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 2082 builder.WriteDataFrameHeader(*this, data.stream_id(), flags);
2083 builder.OverwriteLength(*this, data.data().length()); 2083 builder.OverwriteLength(*this, data.data().length());
2084 DCHECK_EQ(kSize, builder.length()); 2084 DCHECK_EQ(kSize, builder.length());
2085 return builder.take(); 2085 return builder.take();
2086 } 2086 }
2087 2087
2088 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 2088 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
2089 const SpdySynStreamIR& syn_stream) { 2089 const SpdySynStreamIR& syn_stream) {
2090 uint8 flags = 0; 2090 uint8 flags = 0;
2091 if (syn_stream.fin()) { 2091 if (syn_stream.fin()) {
2092 flags |= CONTROL_FLAG_FIN; 2092 flags |= CONTROL_FLAG_FIN;
2093 } 2093 }
2094 if (syn_stream.unidirectional()) { 2094 if (syn_stream.unidirectional()) {
2095 // TODO(hkhalil): invalid for HTTP2. 2095 // TODO(hkhalil): invalid for HTTP2.
2096 flags |= CONTROL_FLAG_UNIDIRECTIONAL; 2096 flags |= CONTROL_FLAG_UNIDIRECTIONAL;
2097 } 2097 }
2098 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now 2098 // In SPDY >= 4, SYN_STREAM frames are HEADERS frames, but for now
2099 // we never expect to have to overflow into a CONTINUATION frame. 2099 // we never expect to have to overflow into a CONTINUATION frame.
2100 if (spdy_version_ >= 4) { 2100 if (protocol_version() > SPDY3) {
2101 flags |= HEADERS_FLAG_PRIORITY; 2101 flags |= HEADERS_FLAG_PRIORITY;
2102 flags |= HEADERS_FLAG_END_HEADERS; 2102 flags |= HEADERS_FLAG_END_HEADERS;
2103 } 2103 }
2104 2104
2105 // Sanitize priority. 2105 // Sanitize priority.
2106 uint8 priority = syn_stream.priority(); 2106 uint8 priority = syn_stream.priority();
2107 if (priority > GetLowestPriority()) { 2107 if (priority > GetLowestPriority()) {
2108 DLOG(DFATAL) << "Priority out-of-bounds."; 2108 DLOG(DFATAL) << "Priority out-of-bounds.";
2109 priority = GetLowestPriority(); 2109 priority = GetLowestPriority();
2110 } 2110 }
2111 2111
2112 // The size of this frame, including variable-length name-value block. 2112 // The size of this frame, including variable-length name-value block.
2113 size_t size = GetSynStreamMinimumSize(); 2113 size_t size = GetSynStreamMinimumSize();
2114 2114
2115 string hpack_encoding; 2115 string hpack_encoding;
2116 if (spdy_version_ >= 4) { 2116 if (protocol_version() > SPDY3) {
2117 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(), 2117 hpack_encoder_.EncodeHeaderSet(syn_stream.name_value_block(),
2118 &hpack_encoding); 2118 &hpack_encoding);
2119 size += hpack_encoding.size(); 2119 size += hpack_encoding.size();
2120 } else { 2120 } else {
2121 size += GetSerializedLength(syn_stream.name_value_block()); 2121 size += GetSerializedLength(syn_stream.name_value_block());
2122 } 2122 }
2123 2123
2124 SpdyFrameBuilder builder(size); 2124 SpdyFrameBuilder builder(size);
2125 if (spdy_version_ < 4) { 2125 if (protocol_version() <= SPDY3) {
2126 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2126 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
2127 builder.WriteUInt32(syn_stream.stream_id()); 2127 builder.WriteUInt32(syn_stream.stream_id());
2128 builder.WriteUInt32(syn_stream.associated_to_stream_id()); 2128 builder.WriteUInt32(syn_stream.associated_to_stream_id());
2129 builder.WriteUInt8(priority << ((spdy_version_ < 3) ? 6 : 5)); 2129 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
2130 builder.WriteUInt8(0); // Unused byte where credential slot used to be. 2130 builder.WriteUInt8(0); // Unused byte where credential slot used to be.
2131 } else { 2131 } else {
2132 builder.WriteFramePrefix(*this, 2132 builder.WriteFramePrefix(*this,
2133 HEADERS, 2133 HEADERS,
2134 flags, 2134 flags,
2135 syn_stream.stream_id()); 2135 syn_stream.stream_id());
2136 builder.WriteUInt32(priority); 2136 builder.WriteUInt32(priority);
2137 } 2137 }
2138 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); 2138 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
2139 if (spdy_version_ >= 4) { 2139 if (protocol_version() > SPDY3) {
2140 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2140 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2141 } else { 2141 } else {
2142 SerializeNameValueBlock(&builder, syn_stream); 2142 SerializeNameValueBlock(&builder, syn_stream);
2143 } 2143 }
2144 2144
2145 if (debug_visitor_) { 2145 if (debug_visitor_) {
2146 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : 2146 const size_t payload_len = protocol_version() > SPDY3 ?
2147 hpack_encoding.size() :
2147 GetSerializedLength(protocol_version(), 2148 GetSerializedLength(protocol_version(),
2148 &(syn_stream.name_value_block())); 2149 &(syn_stream.name_value_block()));
2149 // SPDY 4 reports this compression as a SYN_STREAM compression. 2150 // SPDY 4 reports this compression as a SYN_STREAM compression.
2150 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(), 2151 debug_visitor_->OnSendCompressedFrame(syn_stream.stream_id(),
2151 SYN_STREAM, 2152 SYN_STREAM,
2152 payload_len, 2153 payload_len,
2153 builder.length()); 2154 builder.length());
2154 } 2155 }
2155 2156
2156 return builder.take(); 2157 return builder.take();
2157 } 2158 }
2158 2159
2159 SpdySerializedFrame* SpdyFramer::SerializeSynReply( 2160 SpdySerializedFrame* SpdyFramer::SerializeSynReply(
2160 const SpdySynReplyIR& syn_reply) { 2161 const SpdySynReplyIR& syn_reply) {
2161 uint8 flags = 0; 2162 uint8 flags = 0;
2162 if (syn_reply.fin()) { 2163 if (syn_reply.fin()) {
2163 flags |= CONTROL_FLAG_FIN; 2164 flags |= CONTROL_FLAG_FIN;
2164 } 2165 }
2165 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now 2166 // In SPDY >= 4, SYN_REPLY frames are HEADERS frames, but for now
2166 // we never expect to have to overflow into a CONTINUATION frame. 2167 // we never expect to have to overflow into a CONTINUATION frame.
2167 if (spdy_version_ >= 4) { 2168 if (protocol_version() > SPDY3) {
2168 flags |= HEADERS_FLAG_END_HEADERS; 2169 flags |= HEADERS_FLAG_END_HEADERS;
2169 } 2170 }
2170 2171
2171 // The size of this frame, including variable-length name-value block. 2172 // The size of this frame, including variable-length name-value block.
2172 size_t size = GetSynReplyMinimumSize(); 2173 size_t size = GetSynReplyMinimumSize();
2173 2174
2174 string hpack_encoding; 2175 string hpack_encoding;
2175 if (spdy_version_ >= 4) { 2176 if (protocol_version() > SPDY3) {
2176 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(), 2177 hpack_encoder_.EncodeHeaderSet(syn_reply.name_value_block(),
2177 &hpack_encoding); 2178 &hpack_encoding);
2178 size += hpack_encoding.size(); 2179 size += hpack_encoding.size();
2179 } else { 2180 } else {
2180 size += GetSerializedLength(syn_reply.name_value_block()); 2181 size += GetSerializedLength(syn_reply.name_value_block());
2181 } 2182 }
2182 2183
2183 SpdyFrameBuilder builder(size); 2184 SpdyFrameBuilder builder(size);
2184 if (spdy_version_ < 4) { 2185 if (protocol_version() <= SPDY3) {
2185 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags); 2186 builder.WriteControlFrameHeader(*this, SYN_REPLY, flags);
2186 builder.WriteUInt32(syn_reply.stream_id()); 2187 builder.WriteUInt32(syn_reply.stream_id());
2187 } else { 2188 } else {
2188 builder.WriteFramePrefix(*this, 2189 builder.WriteFramePrefix(*this,
2189 HEADERS, 2190 HEADERS,
2190 flags, 2191 flags,
2191 syn_reply.stream_id()); 2192 syn_reply.stream_id());
2192 } 2193 }
2193 if (protocol_version() < 3) { 2194 if (protocol_version() < SPDY3) {
2194 builder.WriteUInt16(0); // Unused. 2195 builder.WriteUInt16(0); // Unused.
2195 } 2196 }
2196 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length()); 2197 DCHECK_EQ(GetSynReplyMinimumSize(), builder.length());
2197 if (spdy_version_ >= 4) { 2198 if (protocol_version() > SPDY3) {
2198 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2199 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2199 } else { 2200 } else {
2200 SerializeNameValueBlock(&builder, syn_reply); 2201 SerializeNameValueBlock(&builder, syn_reply);
2201 } 2202 }
2202 2203
2203 if (debug_visitor_) { 2204 if (debug_visitor_) {
2204 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : 2205 const size_t payload_len = protocol_version() > SPDY3 ?
2206 hpack_encoding.size() :
2205 GetSerializedLength(protocol_version(), 2207 GetSerializedLength(protocol_version(),
2206 &(syn_reply.name_value_block())); 2208 &(syn_reply.name_value_block()));
2207 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(), 2209 debug_visitor_->OnSendCompressedFrame(syn_reply.stream_id(),
2208 SYN_REPLY, 2210 SYN_REPLY,
2209 payload_len, 2211 payload_len,
2210 builder.length()); 2212 builder.length());
2211 } 2213 }
2212 2214
2213 return builder.take(); 2215 return builder.take();
2214 } 2216 }
2215 2217
2216 SpdySerializedFrame* SpdyFramer::SerializeRstStream( 2218 SpdySerializedFrame* SpdyFramer::SerializeRstStream(
2217 const SpdyRstStreamIR& rst_stream) const { 2219 const SpdyRstStreamIR& rst_stream) const {
2218 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM 2220 // TODO(jgraettinger): For now, Chromium will support parsing RST_STREAM
2219 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2, 2221 // payloads, but will not emit them. SPDY4 is used for draft HTTP/2,
2220 // which doesn't currently include RST_STREAM payloads. GFE flags have been 2222 // which doesn't currently include RST_STREAM payloads. GFE flags have been
2221 // commented but left in place to simplify future patching. 2223 // commented but left in place to simplify future patching.
2222 // Compute the output buffer size, taking opaque data into account. 2224 // Compute the output buffer size, taking opaque data into account.
2223 uint16 expected_length = GetRstStreamMinimumSize(); 2225 uint16 expected_length = GetRstStreamMinimumSize();
2224 if (protocol_version() >= 4) { 2226 if (protocol_version() > SPDY3) {
2225 expected_length += rst_stream.description().size(); 2227 expected_length += rst_stream.description().size();
2226 } 2228 }
2227 SpdyFrameBuilder builder(expected_length); 2229 SpdyFrameBuilder builder(expected_length);
2228 2230
2229 // Serialize the RST_STREAM frame. 2231 // Serialize the RST_STREAM frame.
2230 if (protocol_version() < 4) { 2232 if (protocol_version() <= SPDY3) {
2231 builder.WriteControlFrameHeader(*this, RST_STREAM, 0); 2233 builder.WriteControlFrameHeader(*this, RST_STREAM, 0);
2232 builder.WriteUInt32(rst_stream.stream_id()); 2234 builder.WriteUInt32(rst_stream.stream_id());
2233 } else { 2235 } else {
2234 builder.WriteFramePrefix(*this, RST_STREAM, 0, rst_stream.stream_id()); 2236 builder.WriteFramePrefix(*this, RST_STREAM, 0, rst_stream.stream_id());
2235 } 2237 }
2236 2238
2237 builder.WriteUInt32(rst_stream.status()); 2239 builder.WriteUInt32(rst_stream.status());
2238 2240
2239 // In SPDY4 and up, RST_STREAM frames may also specify opaque data. 2241 // In SPDY4 and up, RST_STREAM frames may also specify opaque data.
2240 if (protocol_version() >= 4 && rst_stream.description().size() > 0) { 2242 if (protocol_version() > SPDY3 && rst_stream.description().size() > 0) {
2241 builder.WriteBytes(rst_stream.description().data(), 2243 builder.WriteBytes(rst_stream.description().data(),
2242 rst_stream.description().size()); 2244 rst_stream.description().size());
2243 } 2245 }
2244 2246
2245 DCHECK_EQ(expected_length, builder.length()); 2247 DCHECK_EQ(expected_length, builder.length());
2246 return builder.take(); 2248 return builder.take();
2247 } 2249 }
2248 2250
2249 SpdySerializedFrame* SpdyFramer::SerializeSettings( 2251 SpdySerializedFrame* SpdyFramer::SerializeSettings(
2250 const SpdySettingsIR& settings) const { 2252 const SpdySettingsIR& settings) const {
2251 uint8 flags = 0; 2253 uint8 flags = 0;
2252 2254
2253 if (spdy_version_ < 4) { 2255 if (protocol_version() <= SPDY3) {
2254 if (settings.clear_settings()) { 2256 if (settings.clear_settings()) {
2255 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS; 2257 flags |= SETTINGS_FLAG_CLEAR_PREVIOUSLY_PERSISTED_SETTINGS;
2256 } 2258 }
2257 } else { 2259 } else {
2258 if (settings.is_ack()) { 2260 if (settings.is_ack()) {
2259 flags |= SETTINGS_FLAG_ACK; 2261 flags |= SETTINGS_FLAG_ACK;
2260 } 2262 }
2261 } 2263 }
2262 const SpdySettingsIR::ValueMap* values = &(settings.values()); 2264 const SpdySettingsIR::ValueMap* values = &(settings.values());
2263 2265
2264 size_t setting_size = (protocol_version() < 4 ? 8 : 5); 2266 size_t setting_size = (protocol_version() <= SPDY3 ? 8 : 5);
2265 // Size, in bytes, of this SETTINGS frame. 2267 // Size, in bytes, of this SETTINGS frame.
2266 const size_t size = GetSettingsMinimumSize() + 2268 const size_t size = GetSettingsMinimumSize() +
2267 (values->size() * setting_size); 2269 (values->size() * setting_size);
2268 SpdyFrameBuilder builder(size); 2270 SpdyFrameBuilder builder(size);
2269 if (spdy_version_ < 4) { 2271 if (protocol_version() <= SPDY3) {
2270 builder.WriteControlFrameHeader(*this, SETTINGS, flags); 2272 builder.WriteControlFrameHeader(*this, SETTINGS, flags);
2271 } else { 2273 } else {
2272 builder.WriteFramePrefix(*this, SETTINGS, flags, 0); 2274 builder.WriteFramePrefix(*this, SETTINGS, flags, 0);
2273 } 2275 }
2274 2276
2275 // If this is an ACK, payload should be empty. 2277 // If this is an ACK, payload should be empty.
2276 if (spdy_version_ >= 4 && settings.is_ack()) { 2278 if (protocol_version() > SPDY3 && settings.is_ack()) {
2277 return builder.take(); 2279 return builder.take();
2278 } 2280 }
2279 2281
2280 if (spdy_version_ < 4) { 2282 if (protocol_version() <= SPDY3) {
2281 builder.WriteUInt32(values->size()); 2283 builder.WriteUInt32(values->size());
2282 } 2284 }
2283 DCHECK_EQ(GetSettingsMinimumSize(), builder.length()); 2285 DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
2284 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin(); 2286 for (SpdySettingsIR::ValueMap::const_iterator it = values->begin();
2285 it != values->end(); 2287 it != values->end();
2286 ++it) { 2288 ++it) {
2287 if (spdy_version_ < 4) { 2289 if (protocol_version() <= SPDY3) {
2288 uint8 setting_flags = 0; 2290 uint8 setting_flags = 0;
2289 if (it->second.persist_value) { 2291 if (it->second.persist_value) {
2290 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST; 2292 setting_flags |= SETTINGS_FLAG_PLEASE_PERSIST;
2291 } 2293 }
2292 if (it->second.persisted) { 2294 if (it->second.persisted) {
2293 setting_flags |= SETTINGS_FLAG_PERSISTED; 2295 setting_flags |= SETTINGS_FLAG_PERSISTED;
2294 } 2296 }
2295 SettingsFlagsAndId flags_and_id(setting_flags, it->first); 2297 SettingsFlagsAndId flags_and_id(setting_flags, it->first);
2296 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version()); 2298 uint32 id_and_flags_wire = flags_and_id.GetWireFormat(protocol_version());
2297 builder.WriteBytes(&id_and_flags_wire, 4); 2299 builder.WriteBytes(&id_and_flags_wire, 4);
2298 } else { 2300 } else {
2299 builder.WriteUInt8(static_cast<uint8>(it->first)); 2301 builder.WriteUInt8(static_cast<uint8>(it->first));
2300 } 2302 }
2301 builder.WriteUInt32(it->second.value); 2303 builder.WriteUInt32(it->second.value);
2302 } 2304 }
2303 DCHECK_EQ(size, builder.length()); 2305 DCHECK_EQ(size, builder.length());
2304 return builder.take(); 2306 return builder.take();
2305 } 2307 }
2306 2308
2307 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const { 2309 SpdyFrame* SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked) const {
2308 DCHECK_LE(4, protocol_version()); 2310 DCHECK_LT(SPDY3, protocol_version());
2309 SpdyFrameBuilder builder(GetBlockedSize()); 2311 SpdyFrameBuilder builder(GetBlockedSize());
2310 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id()); 2312 builder.WriteFramePrefix(*this, BLOCKED, kNoFlags, blocked.stream_id());
2311 return builder.take(); 2313 return builder.take();
2312 } 2314 }
2313 2315
2314 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const { 2316 SpdySerializedFrame* SpdyFramer::SerializePing(const SpdyPingIR& ping) const {
2315 SpdyFrameBuilder builder(GetPingSize()); 2317 SpdyFrameBuilder builder(GetPingSize());
2316 if (spdy_version_ < 4) { 2318 if (protocol_version() <= SPDY3) {
2317 builder.WriteControlFrameHeader(*this, PING, kNoFlags); 2319 builder.WriteControlFrameHeader(*this, PING, kNoFlags);
2318 builder.WriteUInt32(static_cast<uint32>(ping.id())); 2320 builder.WriteUInt32(static_cast<uint32>(ping.id()));
2319 } else { 2321 } else {
2320 uint8 flags = 0; 2322 uint8 flags = 0;
2321 if (ping.is_ack()) { 2323 if (ping.is_ack()) {
2322 flags |= PING_FLAG_ACK; 2324 flags |= PING_FLAG_ACK;
2323 } 2325 }
2324 builder.WriteFramePrefix(*this, PING, flags, 0); 2326 builder.WriteFramePrefix(*this, PING, flags, 0);
2325 builder.WriteUInt64(ping.id()); 2327 builder.WriteUInt64(ping.id());
2326 } 2328 }
2327 DCHECK_EQ(GetPingSize(), builder.length()); 2329 DCHECK_EQ(GetPingSize(), builder.length());
2328 return builder.take(); 2330 return builder.take();
2329 } 2331 }
2330 2332
2331 SpdySerializedFrame* SpdyFramer::SerializeGoAway( 2333 SpdySerializedFrame* SpdyFramer::SerializeGoAway(
2332 const SpdyGoAwayIR& goaway) const { 2334 const SpdyGoAwayIR& goaway) const {
2333 2335
2334 // Compute the output buffer size, take opaque data into account. 2336 // Compute the output buffer size, take opaque data into account.
2335 uint16 expected_length = GetGoAwayMinimumSize(); 2337 uint16 expected_length = GetGoAwayMinimumSize();
2336 if (protocol_version() >= 4) { 2338 if (protocol_version() > SPDY3) {
2337 expected_length += goaway.description().size(); 2339 expected_length += goaway.description().size();
2338 } 2340 }
2339 SpdyFrameBuilder builder(expected_length); 2341 SpdyFrameBuilder builder(expected_length);
2340 2342
2341 // Serialize the GOAWAY frame. 2343 // Serialize the GOAWAY frame.
2342 if (spdy_version_ < 4) { 2344 if (protocol_version() <= SPDY3) {
2343 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags); 2345 builder.WriteControlFrameHeader(*this, GOAWAY, kNoFlags);
2344 } else { 2346 } else {
2345 builder.WriteFramePrefix(*this, GOAWAY, 0, 0); 2347 builder.WriteFramePrefix(*this, GOAWAY, 0, 0);
2346 } 2348 }
2347 2349
2348 // GOAWAY frames specify the last good stream id for all SPDY versions. 2350 // GOAWAY frames specify the last good stream id for all SPDY versions.
2349 builder.WriteUInt32(goaway.last_good_stream_id()); 2351 builder.WriteUInt32(goaway.last_good_stream_id());
2350 2352
2351 // In SPDY3 and up, GOAWAY frames also specify the error status code. 2353 // In SPDY3 and up, GOAWAY frames also specify the error status code.
2352 if (protocol_version() >= 3) { 2354 if (protocol_version() >= SPDY3) {
2353 builder.WriteUInt32(goaway.status()); 2355 builder.WriteUInt32(goaway.status());
2354 } 2356 }
2355 2357
2356 // In SPDY4 and up, GOAWAY frames may also specify opaque data. 2358 // In SPDY4 and up, GOAWAY frames may also specify opaque data.
2357 if ((protocol_version() >= 4) && (goaway.description().size() > 0)) { 2359 if ((protocol_version() > SPDY3) && (goaway.description().size() > 0)) {
2358 builder.WriteBytes(goaway.description().data(), 2360 builder.WriteBytes(goaway.description().data(),
2359 goaway.description().size()); 2361 goaway.description().size());
2360 } 2362 }
2361 2363
2362 DCHECK_EQ(expected_length, builder.length()); 2364 DCHECK_EQ(expected_length, builder.length());
2363 return builder.take(); 2365 return builder.take();
2364 } 2366 }
2365 2367
2366 SpdySerializedFrame* SpdyFramer::SerializeHeaders( 2368 SpdySerializedFrame* SpdyFramer::SerializeHeaders(
2367 const SpdyHeadersIR& headers) { 2369 const SpdyHeadersIR& headers) {
2368 uint8 flags = 0; 2370 uint8 flags = 0;
2369 if (headers.fin()) { 2371 if (headers.fin()) {
2370 flags |= CONTROL_FLAG_FIN; 2372 flags |= CONTROL_FLAG_FIN;
2371 } 2373 }
2372 if (spdy_version_ >= 4) { 2374 if (protocol_version() > SPDY3) {
2373 if (headers.end_headers()) { 2375 if (headers.end_headers()) {
2374 flags |= HEADERS_FLAG_END_HEADERS; 2376 flags |= HEADERS_FLAG_END_HEADERS;
2375 } 2377 }
2376 if (headers.has_priority()) { 2378 if (headers.has_priority()) {
2377 flags |= HEADERS_FLAG_PRIORITY; 2379 flags |= HEADERS_FLAG_PRIORITY;
2378 } 2380 }
2379 } 2381 }
2380 2382
2381 // The size of this frame, including variable-length name-value block. 2383 // The size of this frame, including variable-length name-value block.
2382 size_t size = GetHeadersMinimumSize(); 2384 size_t size = GetHeadersMinimumSize();
2383 2385
2384 uint32 priority = headers.priority(); 2386 uint32 priority = headers.priority();
2385 if (headers.has_priority()) { 2387 if (headers.has_priority()) {
2386 if (priority > GetLowestPriority()) { 2388 if (priority > GetLowestPriority()) {
2387 DLOG(DFATAL) << "Priority out-of-bounds."; 2389 DLOG(DFATAL) << "Priority out-of-bounds.";
2388 priority = GetLowestPriority(); 2390 priority = GetLowestPriority();
2389 } 2391 }
2390 size += 4; 2392 size += 4;
2391 } 2393 }
2392 2394
2393 string hpack_encoding; 2395 string hpack_encoding;
2394 if (spdy_version_ >= 4) { 2396 if (protocol_version() > SPDY3) {
2395 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), &hpack_encoding); 2397 hpack_encoder_.EncodeHeaderSet(headers.name_value_block(), &hpack_encoding);
2396 size += hpack_encoding.size(); 2398 size += hpack_encoding.size();
2397 } else { 2399 } else {
2398 size += GetSerializedLength(headers.name_value_block()); 2400 size += GetSerializedLength(headers.name_value_block());
2399 } 2401 }
2400 2402
2401 SpdyFrameBuilder builder(size); 2403 SpdyFrameBuilder builder(size);
2402 if (spdy_version_ < 4) { 2404 if (protocol_version() <= SPDY3) {
2403 builder.WriteControlFrameHeader(*this, HEADERS, flags); 2405 builder.WriteControlFrameHeader(*this, HEADERS, flags);
2404 builder.WriteUInt32(headers.stream_id()); 2406 builder.WriteUInt32(headers.stream_id());
2405 } else { 2407 } else {
2406 builder.WriteFramePrefix(*this, 2408 builder.WriteFramePrefix(*this,
2407 HEADERS, 2409 HEADERS,
2408 flags, 2410 flags,
2409 headers.stream_id()); 2411 headers.stream_id());
2410 if (headers.has_priority()) { 2412 if (headers.has_priority()) {
2411 builder.WriteUInt32(priority); 2413 builder.WriteUInt32(priority);
2412 } 2414 }
2413 } 2415 }
2414 if (protocol_version() < 3) { 2416 if (protocol_version() <= SPDY2) {
2415 builder.WriteUInt16(0); // Unused. 2417 builder.WriteUInt16(0); // Unused.
2416 } 2418 }
2417 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 2419 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2418 2420
2419 if (spdy_version_ >= 4) { 2421 if (protocol_version() > SPDY3) {
2420 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2422 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2421 } else { 2423 } else {
2422 SerializeNameValueBlock(&builder, headers); 2424 SerializeNameValueBlock(&builder, headers);
2423 } 2425 }
2424 2426
2425 if (debug_visitor_) { 2427 if (debug_visitor_) {
2426 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : 2428 const size_t payload_len = protocol_version() > SPDY3 ?
2429 hpack_encoding.size() :
2427 GetSerializedLength(protocol_version(), 2430 GetSerializedLength(protocol_version(),
2428 &(headers.name_value_block())); 2431 &(headers.name_value_block()));
2429 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), 2432 debug_visitor_->OnSendCompressedFrame(headers.stream_id(),
2430 HEADERS, 2433 HEADERS,
2431 payload_len, 2434 payload_len,
2432 builder.length()); 2435 builder.length());
2433 } 2436 }
2434 2437
2435 return builder.take(); 2438 return builder.take();
2436 } 2439 }
2437 2440
2438 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate( 2441 SpdySerializedFrame* SpdyFramer::SerializeWindowUpdate(
2439 const SpdyWindowUpdateIR& window_update) const { 2442 const SpdyWindowUpdateIR& window_update) const {
2440 SpdyFrameBuilder builder(GetWindowUpdateSize()); 2443 SpdyFrameBuilder builder(GetWindowUpdateSize());
2441 if (spdy_version_ < 4) { 2444 if (protocol_version() <= SPDY3) {
2442 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags); 2445 builder.WriteControlFrameHeader(*this, WINDOW_UPDATE, kNoFlags);
2443 builder.WriteUInt32(window_update.stream_id()); 2446 builder.WriteUInt32(window_update.stream_id());
2444 } else { 2447 } else {
2445 builder.WriteFramePrefix(*this, 2448 builder.WriteFramePrefix(*this,
2446 WINDOW_UPDATE, 2449 WINDOW_UPDATE,
2447 kNoFlags, 2450 kNoFlags,
2448 window_update.stream_id()); 2451 window_update.stream_id());
2449 } 2452 }
2450 builder.WriteUInt32(window_update.delta()); 2453 builder.WriteUInt32(window_update.delta());
2451 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); 2454 DCHECK_EQ(GetWindowUpdateSize(), builder.length());
2452 return builder.take(); 2455 return builder.take();
2453 } 2456 }
2454 2457
2455 SpdyFrame* SpdyFramer::SerializePushPromise( 2458 SpdyFrame* SpdyFramer::SerializePushPromise(
2456 const SpdyPushPromiseIR& push_promise) { 2459 const SpdyPushPromiseIR& push_promise) {
2457 DCHECK_LE(4, protocol_version()); 2460 DCHECK_LT(SPDY3, protocol_version());
2458 uint8 flags = 0; 2461 uint8 flags = 0;
2459 if (push_promise.end_push_promise()) { 2462 if (push_promise.end_push_promise()) {
2460 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2463 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2461 } 2464 }
2462 // The size of this frame, including variable-length name-value block. 2465 // The size of this frame, including variable-length name-value block.
2463 size_t size = GetPushPromiseMinimumSize(); 2466 size_t size = GetPushPromiseMinimumSize();
2464 2467
2465 string hpack_encoding; 2468 string hpack_encoding;
2466 if (spdy_version_ >= 4) { 2469 if (protocol_version() > SPDY3) {
2467 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(), 2470 hpack_encoder_.EncodeHeaderSet(push_promise.name_value_block(),
2468 &hpack_encoding); 2471 &hpack_encoding);
2469 size += hpack_encoding.size(); 2472 size += hpack_encoding.size();
2470 } else { 2473 } else {
2471 size += GetSerializedLength(push_promise.name_value_block()); 2474 size += GetSerializedLength(push_promise.name_value_block());
2472 } 2475 }
2473 2476
2474 SpdyFrameBuilder builder(size); 2477 SpdyFrameBuilder builder(size);
2475 builder.WriteFramePrefix(*this, PUSH_PROMISE, flags, 2478 builder.WriteFramePrefix(*this, PUSH_PROMISE, flags,
2476 push_promise.stream_id()); 2479 push_promise.stream_id());
2477 builder.WriteUInt32(push_promise.promised_stream_id()); 2480 builder.WriteUInt32(push_promise.promised_stream_id());
2478 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length()); 2481 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
2479 2482
2480 if (spdy_version_ >= 4) { 2483 if (protocol_version() > SPDY3) {
2481 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2484 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2482 } else { 2485 } else {
2483 SerializeNameValueBlock(&builder, push_promise); 2486 SerializeNameValueBlock(&builder, push_promise);
2484 } 2487 }
2485 2488
2486 if (debug_visitor_) { 2489 if (debug_visitor_) {
2487 const size_t payload_len = spdy_version_ >= 4 ? hpack_encoding.size() : 2490 const size_t payload_len = protocol_version() > SPDY3 ?
2491 hpack_encoding.size() :
2488 GetSerializedLength(protocol_version(), 2492 GetSerializedLength(protocol_version(),
2489 &(push_promise.name_value_block())); 2493 &(push_promise.name_value_block()));
2490 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), 2494 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(),
2491 PUSH_PROMISE, payload_len, builder.length()); 2495 PUSH_PROMISE, payload_len, builder.length());
2492 } 2496 }
2493 2497
2494 return builder.take(); 2498 return builder.take();
2495 } 2499 }
2496 2500
2497 // TODO(jgraettinger): This implementation is incorrect. The continuation 2501 // TODO(jgraettinger): This implementation is incorrect. The continuation
2498 // frame continues a previously-begun HPACK encoding; it doesn't begin a 2502 // frame continues a previously-begun HPACK encoding; it doesn't begin a
2499 // new one. Figure out whether it makes sense to keep SerializeContinuation(). 2503 // new one. Figure out whether it makes sense to keep SerializeContinuation().
2500 SpdyFrame* SpdyFramer::SerializeContinuation( 2504 SpdyFrame* SpdyFramer::SerializeContinuation(
2501 const SpdyContinuationIR& continuation) { 2505 const SpdyContinuationIR& continuation) {
2502 CHECK_GE(spdy_version_, 4); 2506 CHECK_LT(SPDY3, protocol_version());
2503 uint8 flags = 0; 2507 uint8 flags = 0;
2504 if (continuation.end_headers()) { 2508 if (continuation.end_headers()) {
2505 flags |= HEADERS_FLAG_END_HEADERS; 2509 flags |= HEADERS_FLAG_END_HEADERS;
2506 } 2510 }
2507 2511
2508 // The size of this frame, including variable-length name-value block. 2512 // The size of this frame, including variable-length name-value block.
2509 size_t size = GetContinuationMinimumSize(); 2513 size_t size = GetContinuationMinimumSize();
2510 string hpack_encoding; 2514 string hpack_encoding;
2511 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(), 2515 hpack_encoder_.EncodeHeaderSet(continuation.name_value_block(),
2512 &hpack_encoding); 2516 &hpack_encoding);
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
2584 2588
2585 } // namespace 2589 } // namespace
2586 2590
2587 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) { 2591 SpdySerializedFrame* SpdyFramer::SerializeFrame(const SpdyFrameIR& frame) {
2588 FrameSerializationVisitor visitor(this); 2592 FrameSerializationVisitor visitor(this);
2589 frame.Visit(&visitor); 2593 frame.Visit(&visitor);
2590 return visitor.ReleaseSerializedFrame(); 2594 return visitor.ReleaseSerializedFrame();
2591 } 2595 }
2592 2596
2593 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) { 2597 size_t SpdyFramer::GetSerializedLength(const SpdyHeaderBlock& headers) {
2594 CHECK_LT(spdy_version_, 4); 2598 CHECK_GE(SPDY3, protocol_version());
2595 const size_t uncompressed_length = 2599 const size_t uncompressed_length =
2596 GetSerializedLength(protocol_version(), &headers); 2600 GetSerializedLength(protocol_version(), &headers);
2597 if (!enable_compression_) { 2601 if (!enable_compression_) {
2598 return uncompressed_length; 2602 return uncompressed_length;
2599 } 2603 }
2600 z_stream* compressor = GetHeaderCompressor(); 2604 z_stream* compressor = GetHeaderCompressor();
2601 // Since we'll be performing lots of flushes when compressing the data, 2605 // Since we'll be performing lots of flushes when compressing the data,
2602 // zlib's lower bounds may be insufficient. 2606 // zlib's lower bounds may be insufficient.
2603 return 2 * deflateBound(compressor, uncompressed_length); 2607 return 2 * deflateBound(compressor, uncompressed_length);
2604 } 2608 }
(...skipping 19 matching lines...) Expand all
2624 header_compressor_.reset(new z_stream); 2628 header_compressor_.reset(new z_stream);
2625 memset(header_compressor_.get(), 0, sizeof(z_stream)); 2629 memset(header_compressor_.get(), 0, sizeof(z_stream));
2626 2630
2627 int success = deflateInit2(header_compressor_.get(), 2631 int success = deflateInit2(header_compressor_.get(),
2628 kCompressorLevel, 2632 kCompressorLevel,
2629 Z_DEFLATED, 2633 Z_DEFLATED,
2630 kCompressorWindowSizeInBits, 2634 kCompressorWindowSizeInBits,
2631 kCompressorMemLevel, 2635 kCompressorMemLevel,
2632 Z_DEFAULT_STRATEGY); 2636 Z_DEFAULT_STRATEGY);
2633 if (success == Z_OK) { 2637 if (success == Z_OK) {
2634 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2638 const char* dictionary = (protocol_version() <= SPDY2) ?
2635 : kV3Dictionary; 2639 kV2Dictionary : kV3Dictionary;
2636 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2640 const int dictionary_size = (protocol_version() <= SPDY2) ?
2637 : kV3DictionarySize; 2641 kV2DictionarySize : kV3DictionarySize;
2638 success = deflateSetDictionary(header_compressor_.get(), 2642 success = deflateSetDictionary(header_compressor_.get(),
2639 reinterpret_cast<const Bytef*>(dictionary), 2643 reinterpret_cast<const Bytef*>(dictionary),
2640 dictionary_size); 2644 dictionary_size);
2641 } 2645 }
2642 if (success != Z_OK) { 2646 if (success != Z_OK) {
2643 LOG(WARNING) << "deflateSetDictionary failure: " << success; 2647 LOG(WARNING) << "deflateSetDictionary failure: " << success;
2644 header_compressor_.reset(NULL); 2648 header_compressor_.reset(NULL);
2645 return NULL; 2649 return NULL;
2646 } 2650 }
2647 return header_compressor_.get(); 2651 return header_compressor_.get();
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2687 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we 2691 // If we get a SYN_STREAM/SYN_REPLY/HEADERS frame with stream ID zero, we
2688 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've 2692 // signal an error back in ProcessControlFrameBeforeHeaderBlock. So if we've
2689 // reached this method successfully, stream_id should be nonzero. 2693 // reached this method successfully, stream_id should be nonzero.
2690 DCHECK_LT(0u, stream_id); 2694 DCHECK_LT(0u, stream_id);
2691 while (decomp->avail_in > 0 && processed_successfully) { 2695 while (decomp->avail_in > 0 && processed_successfully) {
2692 decomp->next_out = reinterpret_cast<Bytef*>(buffer); 2696 decomp->next_out = reinterpret_cast<Bytef*>(buffer);
2693 decomp->avail_out = arraysize(buffer); 2697 decomp->avail_out = arraysize(buffer);
2694 2698
2695 int rv = inflate(decomp, Z_SYNC_FLUSH); 2699 int rv = inflate(decomp, Z_SYNC_FLUSH);
2696 if (rv == Z_NEED_DICT) { 2700 if (rv == Z_NEED_DICT) {
2697 const char* dictionary = (spdy_version_ < 3) ? kV2Dictionary 2701 const char* dictionary = (protocol_version() <= SPDY2) ? kV2Dictionary
2698 : kV3Dictionary; 2702 : kV3Dictionary;
2699 const int dictionary_size = (spdy_version_ < 3) ? kV2DictionarySize 2703 const int dictionary_size = (protocol_version() <= SPDY2) ?
2700 : kV3DictionarySize; 2704 kV2DictionarySize : kV3DictionarySize;
2701 const DictionaryIds& ids = g_dictionary_ids.Get(); 2705 const DictionaryIds& ids = g_dictionary_ids.Get();
2702 const uLong dictionary_id = (spdy_version_ < 3) ? ids.v2_dictionary_id 2706 const uLong dictionary_id = (protocol_version() <= SPDY2) ?
2703 : ids.v3_dictionary_id; 2707 ids.v2_dictionary_id : ids.v3_dictionary_id;
2704 // Need to try again with the right dictionary. 2708 // Need to try again with the right dictionary.
2705 if (decomp->adler == dictionary_id) { 2709 if (decomp->adler == dictionary_id) {
2706 rv = inflateSetDictionary(decomp, 2710 rv = inflateSetDictionary(decomp,
2707 reinterpret_cast<const Bytef*>(dictionary), 2711 reinterpret_cast<const Bytef*>(dictionary),
2708 dictionary_size); 2712 dictionary_size);
2709 if (rv == Z_OK) 2713 if (rv == Z_OK)
2710 rv = inflate(decomp, Z_SYNC_FLUSH); 2714 rv = inflate(decomp, Z_SYNC_FLUSH);
2711 } 2715 }
2712 } 2716 }
2713 2717
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
2751 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 2755 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
2752 } 2756 }
2753 } 2757 }
2754 return read_successfully; 2758 return read_successfully;
2755 } 2759 }
2756 2760
2757 void SpdyFramer::SerializeNameValueBlockWithoutCompression( 2761 void SpdyFramer::SerializeNameValueBlockWithoutCompression(
2758 SpdyFrameBuilder* builder, 2762 SpdyFrameBuilder* builder,
2759 const SpdyNameValueBlock& name_value_block) const { 2763 const SpdyNameValueBlock& name_value_block) const {
2760 // Serialize number of headers. 2764 // Serialize number of headers.
2761 if (protocol_version() < 3) { 2765 if (protocol_version() <= SPDY2) {
2762 builder->WriteUInt16(name_value_block.size()); 2766 builder->WriteUInt16(name_value_block.size());
2763 } else { 2767 } else {
2764 builder->WriteUInt32(name_value_block.size()); 2768 builder->WriteUInt32(name_value_block.size());
2765 } 2769 }
2766 2770
2767 // Serialize each header. 2771 // Serialize each header.
2768 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin(); 2772 for (SpdyHeaderBlock::const_iterator it = name_value_block.begin();
2769 it != name_value_block.end(); 2773 it != name_value_block.end();
2770 ++it) { 2774 ++it) {
2771 if (protocol_version() < 3) { 2775 if (protocol_version() <= SPDY2) {
2772 builder->WriteString(it->first); 2776 builder->WriteString(it->first);
2773 builder->WriteString(it->second); 2777 builder->WriteString(it->second);
2774 } else { 2778 } else {
2775 builder->WriteStringPiece32(it->first); 2779 builder->WriteStringPiece32(it->first);
2776 builder->WriteStringPiece32(it->second); 2780 builder->WriteStringPiece32(it->second);
2777 } 2781 }
2778 } 2782 }
2779 } 2783 }
2780 2784
2781 void SpdyFramer::SerializeNameValueBlock( 2785 void SpdyFramer::SerializeNameValueBlock(
2782 SpdyFrameBuilder* builder, 2786 SpdyFrameBuilder* builder,
2783 const SpdyFrameWithNameValueBlockIR& frame) { 2787 const SpdyFrameWithNameValueBlockIR& frame) {
2784 CHECK_LT(spdy_version_, 4); 2788 CHECK_GE(SPDY3, protocol_version());
2785 if (!enable_compression_) { 2789 if (!enable_compression_) {
2786 return SerializeNameValueBlockWithoutCompression(builder, 2790 return SerializeNameValueBlockWithoutCompression(builder,
2787 frame.name_value_block()); 2791 frame.name_value_block());
2788 } 2792 }
2789 2793
2790 // First build an uncompressed version to be fed into the compressor. 2794 // First build an uncompressed version to be fed into the compressor.
2791 const size_t uncompressed_len = GetSerializedLength( 2795 const size_t uncompressed_len = GetSerializedLength(
2792 protocol_version(), &(frame.name_value_block())); 2796 protocol_version(), &(frame.name_value_block()));
2793 SpdyFrameBuilder uncompressed_builder(uncompressed_len); 2797 SpdyFrameBuilder uncompressed_builder(uncompressed_len);
2794 SerializeNameValueBlockWithoutCompression(&uncompressed_builder, 2798 SerializeNameValueBlockWithoutCompression(&uncompressed_builder,
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
2842 builder->Seek(compressed_size); 2846 builder->Seek(compressed_size);
2843 builder->RewriteLength(*this); 2847 builder->RewriteLength(*this);
2844 2848
2845 pre_compress_bytes.Add(uncompressed_len); 2849 pre_compress_bytes.Add(uncompressed_len);
2846 post_compress_bytes.Add(compressed_size); 2850 post_compress_bytes.Add(compressed_size);
2847 2851
2848 compressed_frames.Increment(); 2852 compressed_frames.Increment();
2849 } 2853 }
2850 2854
2851 } // namespace net 2855 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698