OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 // 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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¤t_frame_stream_id_); |
1274 successful_read = reader.ReadUInt31(¤t_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(¤t_frame_stream_id_); | 1333 successful_read = reader.ReadUInt31(¤t_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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(¤t_frame_stream_id_); | 1702 successful_read = reader.ReadUInt31(¤t_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 Loading... |
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(¤t_frame_stream_id_); | 1752 bool successful_read = reader.ReadUInt31(¤t_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 Loading... |
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(¤t_frame_stream_id_); | 1819 bool successful_read = reader.ReadUInt31(¤t_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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |