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

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

Issue 199843005: Implement padding for SPDY4/HTTP2 DATA frames. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nullptr => NULL & discard padding at SpdySession visitor call. Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't 5 // TODO(rtenhove) clean up frame buffer size calculations so that we aren't
6 // constantly adding and subtracting header sizes; this is ugly and error- 6 // constantly adding and subtracting header sizes; this is ugly and error-
7 // prone. 7 // prone.
8 8
9 #include "net/spdy/spdy_framer.h" 9 #include "net/spdy/spdy_framer.h"
10 10
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 previous_state_ = SPDY_RESET; 154 previous_state_ = SPDY_RESET;
155 error_code_ = SPDY_NO_ERROR; 155 error_code_ = SPDY_NO_ERROR;
156 remaining_data_length_ = 0; 156 remaining_data_length_ = 0;
157 remaining_control_header_ = 0; 157 remaining_control_header_ = 0;
158 current_frame_buffer_length_ = 0; 158 current_frame_buffer_length_ = 0;
159 current_frame_type_ = DATA; 159 current_frame_type_ = DATA;
160 current_frame_flags_ = 0; 160 current_frame_flags_ = 0;
161 current_frame_length_ = 0; 161 current_frame_length_ = 0;
162 current_frame_stream_id_ = kInvalidStream; 162 current_frame_stream_id_ = kInvalidStream;
163 settings_scratch_.Reset(); 163 settings_scratch_.Reset();
164 remaining_padding_payload_length_ = 0;
165 remaining_padding_length_fields_ = 0;
164 } 166 }
165 167
166 size_t SpdyFramer::GetDataFrameMinimumSize() const { 168 size_t SpdyFramer::GetDataFrameMinimumSize() const {
167 // Size, in bytes, of the data frame header. Future versions of SPDY 169 // Size, in bytes, of the data frame header. Future versions of SPDY
168 // will likely vary this, so we allow for the flexibility of a function call 170 // will likely vary this, so we allow for the flexibility of a function call
169 // for this value as opposed to a constant. 171 // for this value as opposed to a constant.
170 return 8; 172 return 8;
171 } 173 }
172 174
173 // Size, in bytes, of the control frame header. 175 // Size, in bytes, of the control frame header.
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
342 case SPDY_ERROR: 344 case SPDY_ERROR:
343 return "ERROR"; 345 return "ERROR";
344 case SPDY_AUTO_RESET: 346 case SPDY_AUTO_RESET:
345 return "AUTO_RESET"; 347 return "AUTO_RESET";
346 case SPDY_RESET: 348 case SPDY_RESET:
347 return "RESET"; 349 return "RESET";
348 case SPDY_READING_COMMON_HEADER: 350 case SPDY_READING_COMMON_HEADER:
349 return "READING_COMMON_HEADER"; 351 return "READING_COMMON_HEADER";
350 case SPDY_CONTROL_FRAME_PAYLOAD: 352 case SPDY_CONTROL_FRAME_PAYLOAD:
351 return "CONTROL_FRAME_PAYLOAD"; 353 return "CONTROL_FRAME_PAYLOAD";
354 case SPDY_READ_PADDING_LENGTH:
355 return "SPDY_READ_PADDING_LENGTH";
356 case SPDY_CONSUME_PADDING:
357 return "SPDY_CONSUME_PADDING";
352 case SPDY_IGNORE_REMAINING_PAYLOAD: 358 case SPDY_IGNORE_REMAINING_PAYLOAD:
353 return "IGNORE_REMAINING_PAYLOAD"; 359 return "IGNORE_REMAINING_PAYLOAD";
354 case SPDY_FORWARD_STREAM_FRAME: 360 case SPDY_FORWARD_STREAM_FRAME:
355 return "FORWARD_STREAM_FRAME"; 361 return "FORWARD_STREAM_FRAME";
356 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK: 362 case SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK:
357 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK"; 363 return "SPDY_CONTROL_FRAME_BEFORE_HEADER_BLOCK";
358 case SPDY_CONTROL_FRAME_HEADER_BLOCK: 364 case SPDY_CONTROL_FRAME_HEADER_BLOCK:
359 return "SPDY_CONTROL_FRAME_HEADER_BLOCK"; 365 return "SPDY_CONTROL_FRAME_HEADER_BLOCK";
360 case SPDY_GOAWAY_FRAME_PAYLOAD: 366 case SPDY_GOAWAY_FRAME_PAYLOAD:
361 return "SPDY_GOAWAY_FRAME_PAYLOAD"; 367 return "SPDY_GOAWAY_FRAME_PAYLOAD";
(...skipping 183 matching lines...) Expand 10 before | Expand all | Expand 10 after
545 break; 551 break;
546 } 552 }
547 553
548 case SPDY_CONTROL_FRAME_PAYLOAD: { 554 case SPDY_CONTROL_FRAME_PAYLOAD: {
549 size_t bytes_read = ProcessControlFramePayload(data, len); 555 size_t bytes_read = ProcessControlFramePayload(data, len);
550 len -= bytes_read; 556 len -= bytes_read;
551 data += bytes_read; 557 data += bytes_read;
552 break; 558 break;
553 } 559 }
554 560
561 case SPDY_READ_PADDING_LENGTH: {
562 size_t bytes_read = ProcessFramePaddingLength(data, len);
563 len -= bytes_read;
564 data += bytes_read;
565 break;
566 }
567
568 case SPDY_CONSUME_PADDING: {
569 size_t bytes_read = ProcessFramePadding(data, len);
570 len -= bytes_read;
571 data += bytes_read;
572 break;
573 }
574
555 case SPDY_IGNORE_REMAINING_PAYLOAD: 575 case SPDY_IGNORE_REMAINING_PAYLOAD:
556 // control frame has too-large payload 576 // control frame has too-large payload
557 // intentional fallthrough 577 // intentional fallthrough
558 case SPDY_FORWARD_STREAM_FRAME: { 578 case SPDY_FORWARD_STREAM_FRAME: {
559 size_t bytes_read = ProcessDataFramePayload(data, len); 579 size_t bytes_read = ProcessDataFramePayload(data, len);
560 len -= bytes_read; 580 len -= bytes_read;
561 data += bytes_read; 581 data += bytes_read;
562 break; 582 break;
563 } 583 }
564 default: 584 default:
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
698 } 718 }
699 719
700 // if we're here, then we have the common header all received. 720 // if we're here, then we have the common header all received.
701 if (!is_control_frame) { 721 if (!is_control_frame) {
702 if (protocol_version() >= 4) { 722 if (protocol_version() >= 4) {
703 // Catch bogus tests sending oversized DATA frames. 723 // Catch bogus tests sending oversized DATA frames.
704 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_) 724 DCHECK_GE(GetFrameMaximumSize(), current_frame_length_)
705 << "DATA frame too large for SPDY >= 4."; 725 << "DATA frame too large for SPDY >= 4.";
706 } 726 }
707 727
708 if (current_frame_flags_ & ~DATA_FLAG_FIN) { 728 uint8 valid_data_flags = 0;
729 if (protocol_version() >= 4) {
730 valid_data_flags = DATA_FLAG_FIN | DATA_FLAG_END_SEGMENT |
731 DATA_FLAG_PAD_LOW | DATA_FLAG_PAD_HIGH;
732 } else {
733 valid_data_flags = DATA_FLAG_FIN;
734 }
735
736 if (current_frame_flags_ & ~valid_data_flags) {
709 set_error(SPDY_INVALID_DATA_FRAME_FLAGS); 737 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
710 } else { 738 } else {
711 visitor_->OnDataFrameHeader(current_frame_stream_id_, 739 visitor_->OnDataFrameHeader(current_frame_stream_id_,
712 remaining_data_length_, 740 remaining_data_length_,
713 current_frame_flags_ & DATA_FLAG_FIN); 741 current_frame_flags_ & DATA_FLAG_FIN);
714 if (remaining_data_length_ > 0) { 742 if (remaining_data_length_ > 0) {
715 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME); 743 CHANGE_STATE(SPDY_READ_PADDING_LENGTH);
716 } else { 744 } else {
717 // Empty data frame. 745 // Empty data frame.
718 if (current_frame_flags_ & DATA_FLAG_FIN) { 746 if (current_frame_flags_ & DATA_FLAG_FIN) {
719 visitor_->OnStreamFrameData( 747 visitor_->OnStreamFrameData(
720 current_frame_stream_id_, NULL, 0, true); 748 current_frame_stream_id_, NULL, 0, true);
721 } 749 }
722 CHANGE_STATE(SPDY_AUTO_RESET); 750 CHANGE_STATE(SPDY_AUTO_RESET);
723 } 751 }
724 } 752 }
725 } else if (version != spdy_version_) { 753 } else if (version != spdy_version_) {
(...skipping 1082 matching lines...) Expand 10 before | Expand all | Expand 10 after
1808 if (!processed_successfully) { 1836 if (!processed_successfully) {
1809 set_error(SPDY_RST_STREAM_FRAME_CORRUPT); 1837 set_error(SPDY_RST_STREAM_FRAME_CORRUPT);
1810 } else if (remaining_data_length_ == 0) { 1838 } else if (remaining_data_length_ == 0) {
1811 // Signal that there is not more opaque data. 1839 // Signal that there is not more opaque data.
1812 visitor_->OnRstStreamFrameData(NULL, 0); 1840 visitor_->OnRstStreamFrameData(NULL, 0);
1813 CHANGE_STATE(SPDY_AUTO_RESET); 1841 CHANGE_STATE(SPDY_AUTO_RESET);
1814 } 1842 }
1815 return original_len; 1843 return original_len;
1816 } 1844 }
1817 1845
1846 size_t SpdyFramer::ProcessFramePaddingLength(const char* data, size_t len) {
1847 DCHECK_EQ(SPDY_READ_PADDING_LENGTH, state_);
1848
1849 size_t original_len = len;
1850 if (remaining_padding_length_fields_ == 0) {
1851 DCHECK_EQ(remaining_padding_payload_length_, 0u);
1852 bool pad_low = false;
1853 bool pad_high = false;
1854 if (current_frame_flags_ & net::DATA_FLAG_PAD_LOW) {
1855 pad_low = true;
1856 ++remaining_padding_length_fields_;
1857 }
1858 if (current_frame_flags_ & net::DATA_FLAG_PAD_HIGH) {
1859 pad_high = true;
1860 ++remaining_padding_length_fields_;
1861 }
1862 if ((pad_high && !pad_low) ||
1863 remaining_data_length_ < remaining_padding_length_fields_) {
1864 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1865 return 0;
1866 }
1867 }
1868
1869 // Parse the padding length.
1870 while (len != 0 && remaining_padding_length_fields_ != 0) {
1871 remaining_padding_payload_length_ =
1872 (remaining_padding_payload_length_ << 8) +
1873 *reinterpret_cast<const uint8*>(data);
1874 ++data;
1875 --len;
1876 --remaining_padding_length_fields_;
1877 --remaining_data_length_;
1878 }
1879
1880 if (remaining_padding_length_fields_ == 0) {
1881 if (remaining_padding_payload_length_ > remaining_data_length_) {
1882 set_error(SPDY_INVALID_DATA_FRAME_FLAGS);
1883 return 0;
1884 }
1885 CHANGE_STATE(SPDY_FORWARD_STREAM_FRAME);
1886 }
1887 return original_len - len;
1888 }
1889
1890 size_t SpdyFramer::ProcessFramePadding(const char* data, size_t len) {
1891 DCHECK_EQ(SPDY_CONSUME_PADDING, state_);
1892
1893 size_t original_len = len;
1894 if (remaining_padding_payload_length_ > 0) {
1895 DCHECK_EQ(remaining_padding_payload_length_, remaining_data_length_);
1896 size_t amount_to_discard = std::min(remaining_padding_payload_length_, len);
1897 // The visitor needs to know about padding so it can send window updates.
1898 // Communicate the padding to the visitor through a NULL data pointer, with
1899 // a nonzero size.
1900 if (amount_to_discard) {
1901 visitor_->OnStreamFrameData(
1902 current_frame_stream_id_, NULL, amount_to_discard, false);
1903 }
1904 data += amount_to_discard;
1905 len -= amount_to_discard;
1906 remaining_padding_payload_length_ -= amount_to_discard;
1907 remaining_data_length_ -= amount_to_discard;
1908
1909 // If the FIN flag is set, and there is no more data in this data
1910 // frame, inform the visitor of EOF via a 0-length data frame.
1911 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) {
1912 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1913 }
1914 }
1915
1916 if (remaining_data_length_ == 0) {
1917 CHANGE_STATE(SPDY_AUTO_RESET);
1918 }
1919 return original_len - len;
1920 }
1921
1818 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) { 1922 size_t SpdyFramer::ProcessDataFramePayload(const char* data, size_t len) {
1819 size_t original_len = len; 1923 size_t original_len = len;
1820 1924 if (remaining_data_length_ - remaining_padding_payload_length_ > 0) {
1821 if (remaining_data_length_ > 0) { 1925 size_t amount_to_forward = std::min(
1822 size_t amount_to_forward = std::min(remaining_data_length_, len); 1926 remaining_data_length_ - remaining_padding_payload_length_, len);
1823 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) { 1927 if (amount_to_forward && state_ != SPDY_IGNORE_REMAINING_PAYLOAD) {
1824 // Only inform the visitor if there is data. 1928 // Only inform the visitor if there is data.
1825 if (amount_to_forward) { 1929 if (amount_to_forward) {
1826 visitor_->OnStreamFrameData( 1930 visitor_->OnStreamFrameData(
1827 current_frame_stream_id_, data, amount_to_forward, false); 1931 current_frame_stream_id_, data, amount_to_forward, false);
1828 } 1932 }
1829 } 1933 }
1830 data += amount_to_forward; 1934 data += amount_to_forward;
1831 len -= amount_to_forward; 1935 len -= amount_to_forward;
1832 remaining_data_length_ -= amount_to_forward; 1936 remaining_data_length_ -= amount_to_forward;
1833 1937
1834 // If the FIN flag is set, and there is no more data in this data 1938 // If the FIN flag is set, and there is no more data in this data
1835 // frame, inform the visitor of EOF via a 0-length data frame. 1939 // frame, inform the visitor of EOF via a 0-length data frame.
1836 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) { 1940 if (!remaining_data_length_ && current_frame_flags_ & DATA_FLAG_FIN) {
1837 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true); 1941 visitor_->OnStreamFrameData(current_frame_stream_id_, NULL, 0, true);
1838 } 1942 }
1839 } 1943 }
1840 1944
1841 if (remaining_data_length_ == 0) { 1945 if (remaining_data_length_ == remaining_padding_payload_length_) {
1842 CHANGE_STATE(SPDY_AUTO_RESET); 1946 CHANGE_STATE(SPDY_CONSUME_PADDING);
1843 } 1947 }
1844 return original_len - len; 1948 return original_len - len;
1845 } 1949 }
1846 1950
1847 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data, 1951 size_t SpdyFramer::ParseHeaderBlockInBuffer(const char* header_data,
1848 size_t header_length, 1952 size_t header_length,
1849 SpdyHeaderBlock* block) const { 1953 SpdyHeaderBlock* block) const {
1850 SpdyFrameReader reader(header_data, header_length); 1954 SpdyFrameReader reader(header_data, header_length);
1851 1955
1852 // Read number of headers. 1956 // Read number of headers.
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after
1893 << num_headers << ")."; 1997 << num_headers << ").";
1894 return 0; 1998 return 0;
1895 } 1999 }
1896 2000
1897 // Store header. 2001 // Store header.
1898 (*block)[name] = value; 2002 (*block)[name] = value;
1899 } 2003 }
1900 return reader.GetBytesConsumed(); 2004 return reader.GetBytesConsumed();
1901 } 2005 }
1902 2006
1903 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& data) const { 2007 SpdySerializedFrame* SpdyFramer::SerializeData(const SpdyDataIR& datair) const {
1904 const size_t kSize = GetDataFrameMinimumSize() + data.data().length(); 2008 uint8 flags = DATA_FLAG_NONE;
1905 2009 if (datair.fin()) {
1906 SpdyDataFlags flags = DATA_FLAG_NONE;
1907 if (data.fin()) {
1908 flags = DATA_FLAG_FIN; 2010 flags = DATA_FLAG_FIN;
1909 } 2011 }
1910 2012
1911 SpdyFrameBuilder builder(kSize); 2013 if (protocol_version() >= 4) {
1912 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 2014 int num_padding_fields = 0;
1913 builder.WriteBytes(data.data().data(), data.data().length()); 2015 if (datair.pad_low()) {
1914 DCHECK_EQ(kSize, builder.length()); 2016 flags |= DATA_FLAG_PAD_LOW;
1915 return builder.take(); 2017 ++num_padding_fields;
2018 }
2019 if (datair.pad_high()) {
2020 flags |= DATA_FLAG_PAD_HIGH;
2021 ++num_padding_fields;
2022 }
2023
2024 const size_t size_with_padding = num_padding_fields +
2025 datair.data().length() + datair.padding_payload_len() +
2026 GetDataFrameMinimumSize();
2027 SpdyFrameBuilder builder(size_with_padding);
2028 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags);
2029 if (datair.pad_high()) {
2030 builder.WriteUInt8(datair.padding_payload_len() >> 8);
2031 }
2032 if (datair.pad_low()) {
2033 builder.WriteUInt8(datair.padding_payload_len() & 0xff);
2034 }
2035 builder.WriteBytes(datair.data().data(), datair.data().length());
2036 if (datair.padding_payload_len() > 0) {
2037 string padding = string(datair.padding_payload_len(), '0');
2038 builder.WriteBytes(padding.data(), padding.length());
2039 }
2040 DCHECK_EQ(size_with_padding, builder.length());
2041 return builder.take();
2042 } else {
2043 const size_t size = GetDataFrameMinimumSize() + datair.data().length();
2044 SpdyFrameBuilder builder(size);
2045 builder.WriteDataFrameHeader(*this, datair.stream_id(), flags);
2046 builder.WriteBytes(datair.data().data(), datair.data().length());
2047 DCHECK_EQ(size, builder.length());
2048 return builder.take();
2049 }
1916 } 2050 }
1917 2051
1918 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader( 2052 SpdySerializedFrame* SpdyFramer::SerializeDataFrameHeader(
1919 const SpdyDataIR& data) const { 2053 const SpdyDataIR& data) const {
1920 const size_t kSize = GetDataFrameMinimumSize(); 2054 const size_t kSize = GetDataFrameMinimumSize();
1921 2055
1922 SpdyDataFlags flags = DATA_FLAG_NONE; 2056 uint8 flags = DATA_FLAG_NONE;
1923 if (data.fin()) { 2057 if (data.fin()) {
1924 flags = DATA_FLAG_FIN; 2058 flags = DATA_FLAG_FIN;
1925 } 2059 }
2060 if (protocol_version() >= 4) {
2061 if (data.pad_low()) {
2062 flags |= DATA_FLAG_PAD_LOW;
2063 }
2064 if (data.pad_high()) {
2065 flags |= DATA_FLAG_PAD_HIGH;
2066 }
2067 }
1926 2068
1927 SpdyFrameBuilder builder(kSize); 2069 SpdyFrameBuilder builder(kSize);
1928 builder.WriteDataFrameHeader(*this, data.stream_id(), flags); 2070 builder.WriteDataFrameHeader(*this, data.stream_id(), flags);
1929 if (protocol_version() < 4) { 2071 if (protocol_version() >= 4) {
2072 builder.OverwriteLength(*this, data.data().length() + kSize);
2073 } else {
1930 builder.OverwriteLength(*this, data.data().length()); 2074 builder.OverwriteLength(*this, data.data().length());
1931 } else {
1932 builder.OverwriteLength(*this, data.data().length() + kSize);
1933 } 2075 }
1934 DCHECK_EQ(kSize, builder.length()); 2076 DCHECK_EQ(kSize, builder.length());
1935 return builder.take(); 2077 return builder.take();
1936 } 2078 }
1937 2079
1938 SpdySerializedFrame* SpdyFramer::SerializeSynStream( 2080 SpdySerializedFrame* SpdyFramer::SerializeSynStream(
1939 const SpdySynStreamIR& syn_stream) { 2081 const SpdySynStreamIR& syn_stream) {
1940 uint8 flags = 0; 2082 uint8 flags = 0;
1941 if (syn_stream.fin()) { 2083 if (syn_stream.fin()) {
1942 flags |= CONTROL_FLAG_FIN; 2084 flags |= CONTROL_FLAG_FIN;
(...skipping 749 matching lines...) Expand 10 before | Expand all | Expand 10 after
2692 builder->Seek(compressed_size); 2834 builder->Seek(compressed_size);
2693 builder->RewriteLength(*this); 2835 builder->RewriteLength(*this);
2694 2836
2695 pre_compress_bytes.Add(uncompressed_len); 2837 pre_compress_bytes.Add(uncompressed_len);
2696 post_compress_bytes.Add(compressed_size); 2838 post_compress_bytes.Add(compressed_size);
2697 2839
2698 compressed_frames.Increment(); 2840 compressed_frames.Increment();
2699 } 2841 }
2700 2842
2701 } // namespace net 2843 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698