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 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 |
OLD | NEW |