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

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

Issue 2753043002: Create new versions of SerializeXXX() functions that uses pre-allocated buffer in SpdyFrameBuilder. (Closed)
Patch Set: htonl change Created 3 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
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 #include "net/spdy/spdy_framer.h" 5 #include "net/spdy/spdy_framer.h"
6 6
7 #include <string.h> 7 #include <string.h>
8 8
9 #include <algorithm> 9 #include <algorithm>
10 #include <cctype> 10 #include <cctype>
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after
107 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1); 107 const SpdyStreamId SpdyFramer::kInvalidStream = static_cast<SpdyStreamId>(-1);
108 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 108 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
109 // Even though the length field is 24 bits, we keep this 16 kB 109 // Even though the length field is 24 bits, we keep this 16 kB
110 // limit on control frame size for legacy reasons and to 110 // limit on control frame size for legacy reasons and to
111 // mitigate DOS attacks. 111 // mitigate DOS attacks.
112 const size_t SpdyFramer::kMaxControlFrameSize = (1 << 14) - 1; 112 const size_t SpdyFramer::kMaxControlFrameSize = (1 << 14) - 1;
113 const size_t SpdyFramer::kMaxDataPayloadSendSize = 1 << 14; 113 const size_t SpdyFramer::kMaxDataPayloadSendSize = 1 << 14;
114 // The size of the control frame buffer. Must be >= the minimum size of the 114 // The size of the control frame buffer. Must be >= the minimum size of the
115 // largest control frame. 115 // largest control frame.
116 const size_t SpdyFramer::kControlFrameBufferSize = 19; 116 const size_t SpdyFramer::kControlFrameBufferSize = 19;
117 const size_t SpdyFramer::kOneSettingParameterSize = 6;
117 118
118 #ifdef DEBUG_SPDY_STATE_CHANGES 119 #ifdef DEBUG_SPDY_STATE_CHANGES
119 #define CHANGE_STATE(newstate) \ 120 #define CHANGE_STATE(newstate) \
120 do { \ 121 do { \
121 DVLOG(1) << "Changing state from: " \ 122 DVLOG(1) << "Changing state from: " \
122 << StateToString(state_) \ 123 << StateToString(state_) \
123 << " to " << StateToString(newstate) << "\n"; \ 124 << " to " << StateToString(newstate) << "\n"; \
124 DCHECK(state_ != SPDY_ERROR); \ 125 DCHECK(state_ != SPDY_ERROR); \
125 DCHECK_EQ(previous_state_, state_); \ 126 DCHECK_EQ(previous_state_, state_); \
126 previous_state_ = state_; \ 127 previous_state_ = state_; \
(...skipping 645 matching lines...) Expand 10 before | Expand all | Expand 10 after
772 } else if (current_frame_flags_ != 0) { 773 } else if (current_frame_flags_ != 0) {
773 VLOG(1) << "Undefined frame flags for RST_STREAM frame: " << hex 774 VLOG(1) << "Undefined frame flags for RST_STREAM frame: " << hex
774 << static_cast<int>(current_frame_flags_); 775 << static_cast<int>(current_frame_flags_);
775 current_frame_flags_ = 0; 776 current_frame_flags_ = 0;
776 } 777 }
777 break; 778 break;
778 case SETTINGS: 779 case SETTINGS:
779 { 780 {
780 // Make sure that we have an integral number of 8-byte key/value pairs, 781 // Make sure that we have an integral number of 8-byte key/value pairs,
781 // Size of each key/value pair in bytes. 782 // Size of each key/value pair in bytes.
782 int setting_size = 6;
783 if (current_frame_length_ < GetSettingsMinimumSize() || 783 if (current_frame_length_ < GetSettingsMinimumSize() ||
784 (current_frame_length_ - GetFrameHeaderSize()) % setting_size != 0) { 784 (current_frame_length_ - GetFrameHeaderSize()) %
785 kOneSettingParameterSize !=
786 0) {
785 DLOG(WARNING) << "Invalid length for SETTINGS frame: " 787 DLOG(WARNING) << "Invalid length for SETTINGS frame: "
786 << current_frame_length_; 788 << current_frame_length_;
787 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); 789 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE);
788 } else if (current_frame_flags_ & SETTINGS_FLAG_ACK && 790 } else if (current_frame_flags_ & SETTINGS_FLAG_ACK &&
789 current_frame_length_ > GetSettingsMinimumSize()) { 791 current_frame_length_ > GetSettingsMinimumSize()) {
790 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE); 792 set_error(SPDY_INVALID_CONTROL_FRAME_SIZE);
791 } else if (current_frame_flags_ & ~SETTINGS_FLAG_ACK) { 793 } else if (current_frame_flags_ & ~SETTINGS_FLAG_ACK) {
792 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex 794 VLOG(1) << "Undefined frame flags for SETTINGS frame: " << hex
793 << static_cast<int>(current_frame_flags_); 795 << static_cast<int>(current_frame_flags_);
794 current_frame_flags_ &= SETTINGS_FLAG_ACK; 796 current_frame_flags_ &= SETTINGS_FLAG_ACK;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
1256 return bytes_read; 1258 return bytes_read;
1257 } 1259 }
1258 1260
1259 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data, 1261 size_t SpdyFramer::ProcessSettingsFramePayload(const char* data,
1260 size_t data_len) { 1262 size_t data_len) {
1261 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_); 1263 DCHECK_EQ(SPDY_SETTINGS_FRAME_PAYLOAD, state_);
1262 DCHECK_EQ(SETTINGS, current_frame_type_); 1264 DCHECK_EQ(SETTINGS, current_frame_type_);
1263 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_); 1265 size_t unprocessed_bytes = std::min(data_len, remaining_data_length_);
1264 size_t processed_bytes = 0; 1266 size_t processed_bytes = 0;
1265 1267
1266 size_t setting_size = 6;
1267
1268 // Loop over our incoming data. 1268 // Loop over our incoming data.
1269 while (unprocessed_bytes > 0) { 1269 while (unprocessed_bytes > 0) {
1270 // Process up to one setting at a time. 1270 // Process up to one setting at a time.
1271 size_t processing = std::min(unprocessed_bytes, 1271 size_t processing =
1272 setting_size - settings_scratch_.buffer.len()); 1272 std::min(unprocessed_bytes,
1273 kOneSettingParameterSize - settings_scratch_.buffer.len());
1273 1274
1274 // Check if we have a complete setting in our input. 1275 // Check if we have a complete setting in our input.
1275 if (processing == setting_size) { 1276 if (processing == kOneSettingParameterSize) {
1276 // Parse the setting directly out of the input without buffering. 1277 // Parse the setting directly out of the input without buffering.
1277 if (!ProcessSetting(data + processed_bytes)) { 1278 if (!ProcessSetting(data + processed_bytes)) {
1278 set_error(SPDY_INVALID_CONTROL_FRAME); 1279 set_error(SPDY_INVALID_CONTROL_FRAME);
1279 return processed_bytes; 1280 return processed_bytes;
1280 } 1281 }
1281 } else { 1282 } else {
1282 // Continue updating settings_scratch_.setting_buf. 1283 // Continue updating settings_scratch_.setting_buf.
1283 settings_scratch_.buffer.CopyFrom(data + processed_bytes, processing); 1284 settings_scratch_.buffer.CopyFrom(data + processed_bytes, processing);
1284 1285
1285 // Check if we have a complete setting buffered. 1286 // Check if we have a complete setting buffered.
1286 if (settings_scratch_.buffer.len() == setting_size) { 1287 if (settings_scratch_.buffer.len() == kOneSettingParameterSize) {
1287 if (!ProcessSetting(settings_scratch_.buffer.data())) { 1288 if (!ProcessSetting(settings_scratch_.buffer.data())) {
1288 set_error(SPDY_INVALID_CONTROL_FRAME); 1289 set_error(SPDY_INVALID_CONTROL_FRAME);
1289 return processed_bytes; 1290 return processed_bytes;
1290 } 1291 }
1291 // Rewind settings buffer for our next setting. 1292 // Rewind settings buffer for our next setting.
1292 settings_scratch_.buffer.Rewind(); 1293 settings_scratch_.buffer.Rewind();
1293 } 1294 }
1294 } 1295 }
1295 1296
1296 // Iterate. 1297 // Iterate.
(...skipping 441 matching lines...) Expand 10 before | Expand all | Expand 10 after
1738 headers_ir_->set_end_headers(!has_next_frame_); 1739 headers_ir_->set_end_headers(!has_next_frame_);
1739 return framer_->SerializeHeadersGivenEncoding(*headers_ir_, *encoding); 1740 return framer_->SerializeHeadersGivenEncoding(*headers_ir_, *encoding);
1740 } else { 1741 } else {
1741 SpdyContinuationIR continuation_ir(headers_ir_->stream_id()); 1742 SpdyContinuationIR continuation_ir(headers_ir_->stream_id());
1742 continuation_ir.set_end_headers(!has_next_frame_); 1743 continuation_ir.set_end_headers(!has_next_frame_);
1743 continuation_ir.take_encoding(std::move(encoding)); 1744 continuation_ir.take_encoding(std::move(encoding));
1744 return framer_->SerializeContinuation(continuation_ir); 1745 return framer_->SerializeContinuation(continuation_ir);
1745 } 1746 }
1746 } 1747 }
1747 1748
1749 void SpdyFramer::SerializeDataBuilderHelper(const SpdyDataIR& data_ir,
1750 uint8_t* flags,
1751 int* num_padding_fields,
1752 size_t* size_with_padding) const {
1753 if (data_ir.fin()) {
1754 *flags = DATA_FLAG_FIN;
1755 }
1756
1757 if (data_ir.padded()) {
1758 *flags = *flags | DATA_FLAG_PADDED;
1759 ++*num_padding_fields;
1760 }
1761
1762 *size_with_padding = *num_padding_fields + data_ir.data_len() +
1763 data_ir.padding_payload_len() +
1764 GetDataFrameMinimumSize();
1765 }
1766
1748 SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const { 1767 SpdySerializedFrame SpdyFramer::SerializeData(const SpdyDataIR& data_ir) const {
1749 uint8_t flags = DATA_FLAG_NONE; 1768 uint8_t flags = DATA_FLAG_NONE;
1750 if (data_ir.fin()) { 1769 int num_padding_fields = 0;
1751 flags = DATA_FLAG_FIN; 1770 size_t size_with_padding = 0;
1752 } 1771 SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
1772 &size_with_padding);
1753 1773
1754 int num_padding_fields = 0;
1755 if (data_ir.padded()) {
1756 flags |= DATA_FLAG_PADDED;
1757 ++num_padding_fields;
1758 }
1759
1760 const size_t size_with_padding = num_padding_fields + data_ir.data_len() +
1761 data_ir.padding_payload_len() +
1762 GetDataFrameMinimumSize();
1763 SpdyFrameBuilder builder(size_with_padding); 1774 SpdyFrameBuilder builder(size_with_padding);
1764 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); 1775 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id());
1765 if (data_ir.padded()) { 1776 if (data_ir.padded()) {
1766 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); 1777 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
1767 } 1778 }
1768 builder.WriteBytes(data_ir.data(), data_ir.data_len()); 1779 builder.WriteBytes(data_ir.data(), data_ir.data_len());
1769 if (data_ir.padding_payload_len() > 0) { 1780 if (data_ir.padding_payload_len() > 0) {
1770 string padding(data_ir.padding_payload_len(), 0); 1781 string padding(data_ir.padding_payload_len(), 0);
1771 builder.WriteBytes(padding.data(), padding.length()); 1782 builder.WriteBytes(padding.data(), padding.length());
1772 } 1783 }
1773 DCHECK_EQ(size_with_padding, builder.length()); 1784 DCHECK_EQ(size_with_padding, builder.length());
1774 return builder.take(); 1785 return builder.take();
1775 } 1786 }
1776 1787
1788 void SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
1789 const SpdyDataIR& data_ir,
1790 uint8_t* flags,
1791 size_t* frame_size,
1792 size_t* num_padding_fields) const {
1793 *flags = DATA_FLAG_NONE;
1794 if (data_ir.fin()) {
1795 *flags = DATA_FLAG_FIN;
1796 }
1797
1798 *frame_size = GetDataFrameMinimumSize();
1799 if (data_ir.padded()) {
1800 *flags = *flags | DATA_FLAG_PADDED;
1801 ++(*num_padding_fields);
1802 *frame_size = *frame_size + *num_padding_fields;
1803 }
1804 }
1805
1777 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( 1806 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
1778 const SpdyDataIR& data_ir) const { 1807 const SpdyDataIR& data_ir) const {
1779 uint8_t flags = DATA_FLAG_NONE; 1808 uint8_t flags = DATA_FLAG_NONE;
1780 if (data_ir.fin()) { 1809 size_t frame_size = 0;
1781 flags = DATA_FLAG_FIN;
1782 }
1783
1784 size_t frame_size = GetDataFrameMinimumSize();
1785 size_t num_padding_fields = 0; 1810 size_t num_padding_fields = 0;
1786 if (data_ir.padded()) { 1811 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
1787 flags |= DATA_FLAG_PADDED; 1812 data_ir, &flags, &frame_size, &num_padding_fields);
1788 ++num_padding_fields;
1789 frame_size += num_padding_fields;
1790 }
1791 1813
1792 SpdyFrameBuilder builder(frame_size); 1814 SpdyFrameBuilder builder(frame_size);
1793 if (!skip_rewritelength_) { 1815 if (!skip_rewritelength_) {
1794 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); 1816 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id());
1795 if (data_ir.padded()) { 1817 if (data_ir.padded()) {
1796 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); 1818 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
1797 } 1819 }
1798 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + 1820 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() +
1799 data_ir.padding_payload_len()); 1821 data_ir.padding_payload_len());
1800 } else { 1822 } else {
(...skipping 14 matching lines...) Expand all
1815 SpdyFrameBuilder builder(expected_length); 1837 SpdyFrameBuilder builder(expected_length);
1816 1838
1817 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); 1839 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
1818 1840
1819 builder.WriteUInt32(rst_stream.error_code()); 1841 builder.WriteUInt32(rst_stream.error_code());
1820 1842
1821 DCHECK_EQ(expected_length, builder.length()); 1843 DCHECK_EQ(expected_length, builder.length());
1822 return builder.take(); 1844 return builder.take();
1823 } 1845 }
1824 1846
1847 void SpdyFramer::SerializeSettingsBuilderHelper(const SpdySettingsIR& settings,
1848 uint8_t* flags,
1849 const SettingsMap* values,
1850 size_t* size) const {
1851 if (settings.is_ack()) {
1852 *flags = *flags | SETTINGS_FLAG_ACK;
1853 }
1854 *size =
1855 GetSettingsMinimumSize() + (values->size() * kOneSettingParameterSize);
1856 }
1857
1825 SpdySerializedFrame SpdyFramer::SerializeSettings( 1858 SpdySerializedFrame SpdyFramer::SerializeSettings(
Bence 2017/03/16 18:12:54 9 lines were removed from this method and 6 added
yasong 2017/03/16 22:28:52 Nice catch!! How did find them?
Bence 2017/03/16 22:40:58 By going through the two diffs side by side. Unfo
1826 const SpdySettingsIR& settings) const { 1859 const SpdySettingsIR& settings) const {
1827 uint8_t flags = 0; 1860 uint8_t flags = 0;
1828 1861
1829 if (settings.is_ack()) { 1862 if (settings.is_ack()) {
1830 flags |= SETTINGS_FLAG_ACK; 1863 flags |= SETTINGS_FLAG_ACK;
1831 } 1864 }
1832 const SettingsMap* values = &(settings.values()); 1865 const SettingsMap* values = &(settings.values());
1833 1866
1834 int setting_size = 6; 1867 int setting_size = 6;
1835 // Size, in bytes, of this SETTINGS frame. 1868 // Size, in bytes, of this SETTINGS frame.
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
1886 // GOAWAY frames may also specify opaque data. 1919 // GOAWAY frames may also specify opaque data.
1887 if (!goaway.description().empty()) { 1920 if (!goaway.description().empty()) {
1888 builder.WriteBytes(goaway.description().data(), 1921 builder.WriteBytes(goaway.description().data(),
1889 goaway.description().size()); 1922 goaway.description().size());
1890 } 1923 }
1891 1924
1892 DCHECK_EQ(expected_length, builder.length()); 1925 DCHECK_EQ(expected_length, builder.length());
1893 return builder.take(); 1926 return builder.take();
1894 } 1927 }
1895 1928
1929 void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers,
1930 uint8_t* flags,
1931 size_t* size,
1932 string* hpack_encoding,
1933 int* weight,
1934 size_t* length_field) {
1935 if (headers.fin()) {
1936 *flags = *flags | CONTROL_FLAG_FIN;
1937 }
1938 // This will get overwritten if we overflow into a CONTINUATION frame.
1939 *flags = *flags | HEADERS_FLAG_END_HEADERS;
1940 if (headers.has_priority()) {
1941 *flags = *flags | HEADERS_FLAG_PRIORITY;
1942 }
1943 if (headers.padded()) {
1944 *flags = *flags | HEADERS_FLAG_PADDED;
1945 }
1946
1947 *size = GetHeadersMinimumSize();
1948
1949 if (headers.padded()) {
1950 *size = *size + kPadLengthFieldSize;
1951 *size = *size + headers.padding_payload_len();
1952 }
1953
1954 if (headers.has_priority()) {
1955 *weight = ClampHttp2Weight(headers.weight());
1956 *size = *size + 5;
1957 }
1958
1959 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), hpack_encoding);
1960 *size = *size + hpack_encoding->size();
1961 if (*size > kMaxControlFrameSize) {
1962 *size = *size + GetNumberRequiredContinuationFrames(*size) *
1963 GetContinuationMinimumSize();
1964 *flags = *flags & ~HEADERS_FLAG_END_HEADERS;
1965 }
1966 // Compute frame length field.
1967 if (headers.padded()) {
1968 *length_field = *length_field + 1; // Padding length field.
1969 }
1970 if (headers.has_priority()) {
1971 *length_field = *length_field + 4; // Dependency field.
1972 *length_field = *length_field + 1; // Weight field.
1973 }
1974 *length_field = *length_field + headers.padding_payload_len();
1975 *length_field = *length_field + hpack_encoding->size();
1976 // If the HEADERS frame with payload would exceed the max frame size, then
1977 // WritePayloadWithContinuation() will serialize CONTINUATION frames as
1978 // necessary.
1979 *length_field =
1980 std::min(*length_field, kMaxControlFrameSize - GetFrameHeaderSize());
1981 }
1982
1896 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { 1983 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) {
1897 uint8_t flags = 0; 1984 uint8_t flags = 0;
1898 if (headers.fin()) {
1899 flags |= CONTROL_FLAG_FIN;
1900 }
1901 // This will get overwritten if we overflow into a CONTINUATION frame.
1902 flags |= HEADERS_FLAG_END_HEADERS;
1903 if (headers.has_priority()) {
1904 flags |= HEADERS_FLAG_PRIORITY;
1905 }
1906 if (headers.padded()) {
1907 flags |= HEADERS_FLAG_PADDED;
1908 }
1909
1910 // The size of this frame, including padding (if there is any) and 1985 // The size of this frame, including padding (if there is any) and
1911 // variable-length header block. 1986 // variable-length header block.
1912 size_t size = GetHeadersMinimumSize(); 1987 size_t size = 0;
1913 1988 string hpack_encoding;
1914 if (headers.padded()) {
1915 size += kPadLengthFieldSize;
1916 size += headers.padding_payload_len();
1917 }
1918
1919 int weight = 0; 1989 int weight = 0;
1920 if (headers.has_priority()) { 1990 size_t length_field = 0;
1921 weight = ClampHttp2Weight(headers.weight()); 1991 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
1922 size += 5; 1992 &weight, &length_field);
1923 }
1924
1925 string hpack_encoding;
1926 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding);
1927 size += hpack_encoding.size();
1928 if (size > kMaxControlFrameSize) {
1929 size += GetNumberRequiredContinuationFrames(size) *
1930 GetContinuationMinimumSize();
1931 flags &= ~HEADERS_FLAG_END_HEADERS;
1932 }
1933 1993
1934 SpdyFrameBuilder builder(size); 1994 SpdyFrameBuilder builder(size);
1935 1995
1936 if (!skip_rewritelength_) { 1996 if (!skip_rewritelength_) {
1937 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); 1997 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id());
1938 } else { 1998 } else {
1939 // Compute frame length field.
1940 size_t length_field = 0;
1941 if (headers.padded()) {
1942 length_field += 1; // Padding length field.
1943 }
1944 if (headers.has_priority()) {
1945 length_field += 4; // Dependency field.
1946 length_field += 1; // Weight field.
1947 }
1948 length_field += headers.padding_payload_len();
1949 length_field += hpack_encoding.size();
1950 // If the HEADERS frame with payload would exceed the max frame size, then
1951 // WritePayloadWithContinuation() will serialize CONTINUATION frames as
1952 // necessary.
1953 length_field =
1954 std::min(length_field, kMaxControlFrameSize - GetFrameHeaderSize());
1955 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id(), 1999 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id(),
1956 length_field); 2000 length_field);
1957 } 2001 }
1958 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 2002 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
1959 2003
1960 int padding_payload_len = 0; 2004 int padding_payload_len = 0;
1961 if (headers.padded()) { 2005 if (headers.padded()) {
1962 builder.WriteUInt8(headers.padding_payload_len()); 2006 builder.WriteUInt8(headers.padding_payload_len());
1963 padding_payload_len = headers.padding_payload_len(); 2007 padding_payload_len = headers.padding_payload_len();
1964 } 2008 }
(...skipping 30 matching lines...) Expand all
1995 return builder.take(); 2039 return builder.take();
1996 } 2040 }
1997 2041
1998 SpdySerializedFrame SpdyFramer::SerializeBlocked( 2042 SpdySerializedFrame SpdyFramer::SerializeBlocked(
1999 const SpdyBlockedIR& blocked) const { 2043 const SpdyBlockedIR& blocked) const {
2000 SpdyFrameBuilder builder(GetBlockedSize()); 2044 SpdyFrameBuilder builder(GetBlockedSize());
2001 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id()); 2045 builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2002 return builder.take(); 2046 return builder.take();
2003 } 2047 }
2004 2048
2049 void SpdyFramer::SerializePushPromiseBuilderHelper(
2050 const SpdyPushPromiseIR& push_promise,
2051 uint8_t* flags,
2052 string* hpack_encoding,
2053 size_t* size) {
2054 *flags = 0;
2055 // This will get overwritten if we overflow into a CONTINUATION frame.
2056 *flags = *flags | PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2057 // The size of this frame, including variable-length name-value block.
2058 *size = GetPushPromiseMinimumSize();
2059
2060 if (push_promise.padded()) {
2061 *flags = *flags | PUSH_PROMISE_FLAG_PADDED;
2062 *size = *size + kPadLengthFieldSize;
2063 *size = *size + push_promise.padding_payload_len();
2064 }
2065
2066 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(),
2067 hpack_encoding);
2068 *size = *size + hpack_encoding->size();
2069 if (*size > kMaxControlFrameSize) {
2070 *size = *size + GetNumberRequiredContinuationFrames(*size) *
2071 GetContinuationMinimumSize();
2072 *flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2073 }
2074 }
2075
2005 SpdySerializedFrame SpdyFramer::SerializePushPromise( 2076 SpdySerializedFrame SpdyFramer::SerializePushPromise(
2006 const SpdyPushPromiseIR& push_promise) { 2077 const SpdyPushPromiseIR& push_promise) {
2007 uint8_t flags = 0; 2078 uint8_t flags = 0;
2008 // This will get overwritten if we overflow into a CONTINUATION frame. 2079 size_t size = 0;
2009 flags |= PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2010 // The size of this frame, including variable-length name-value block.
2011 size_t size = GetPushPromiseMinimumSize();
2012
2013 if (push_promise.padded()) {
2014 flags |= PUSH_PROMISE_FLAG_PADDED;
2015 size += kPadLengthFieldSize;
2016 size += push_promise.padding_payload_len();
2017 }
2018
2019 string hpack_encoding; 2080 string hpack_encoding;
2020 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), 2081 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
2021 &hpack_encoding); 2082 &size);
2022 size += hpack_encoding.size();
2023 if (size > kMaxControlFrameSize) {
2024 size += GetNumberRequiredContinuationFrames(size) *
2025 GetContinuationMinimumSize();
2026 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2027 }
2028 2083
2029 SpdyFrameBuilder builder(size); 2084 SpdyFrameBuilder builder(size);
2030 if (!skip_rewritelength_) { 2085 if (!skip_rewritelength_) {
2031 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id()); 2086 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id());
2032 } else { 2087 } else {
2033 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); 2088 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize();
2034 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id(), 2089 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id(),
2035 length); 2090 length);
2036 } 2091 }
2037 int padding_payload_len = 0; 2092 int padding_payload_len = 0;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
2100 2155
2101 SpdySerializedFrame SpdyFramer::SerializeContinuation( 2156 SpdySerializedFrame SpdyFramer::SerializeContinuation(
2102 const SpdyContinuationIR& continuation) const { 2157 const SpdyContinuationIR& continuation) const {
2103 const string& encoding = continuation.encoding(); 2158 const string& encoding = continuation.encoding();
2104 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); 2159 size_t frame_size = GetContinuationMinimumSize() + encoding.size();
2105 SpdyFrameBuilder builder(frame_size); 2160 SpdyFrameBuilder builder(frame_size);
2106 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; 2161 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
2107 builder.BeginNewFrame(*this, CONTINUATION, flags, continuation.stream_id()); 2162 builder.BeginNewFrame(*this, CONTINUATION, flags, continuation.stream_id());
2108 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); 2163 DCHECK_EQ(GetFrameHeaderSize(), builder.length());
2109 2164
2110 builder.WriteBytes(&encoding[0], encoding.size()); 2165 builder.WriteBytes(encoding.data(), encoding.size());
2111 return builder.take(); 2166 return builder.take();
2112 } 2167 }
2113 2168
2169 void SpdyFramer::SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir,
2170 string* value,
2171 size_t* size) const {
2172 *size = GetAltSvcMinimumSize();
2173 *size = *size + altsvc_ir.origin().length();
2174 *value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
2175 altsvc_ir.altsvc_vector());
2176 *size = *size + value->length();
2177 }
2178
2114 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { 2179 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) {
2115 size_t size = GetAltSvcMinimumSize(); 2180 string value;
2116 size += altsvc_ir.origin().length(); 2181 size_t size = 0;
2117 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( 2182 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
2118 altsvc_ir.altsvc_vector());
2119 size += value.length();
2120
2121 SpdyFrameBuilder builder(size); 2183 SpdyFrameBuilder builder(size);
2122 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id()); 2184 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id());
2123 2185
2124 builder.WriteUInt16(altsvc_ir.origin().length()); 2186 builder.WriteUInt16(altsvc_ir.origin().length());
2125 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); 2187 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length());
2126 builder.WriteBytes(value.data(), value.length()); 2188 builder.WriteBytes(value.data(), value.length());
2127 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); 2189 DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
2128 return builder.take(); 2190 return builder.take();
2129 } 2191 }
2130 2192
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
2285 frame.Visit(&visitor); 2347 frame.Visit(&visitor);
2286 return visitor.ReleaseSerializedFrame(); 2348 return visitor.ReleaseSerializedFrame();
2287 } 2349 }
2288 2350
2289 uint8_t SpdyFramer::GetSerializedFlags(const SpdyFrameIR& frame) { 2351 uint8_t SpdyFramer::GetSerializedFlags(const SpdyFrameIR& frame) {
2290 FlagsSerializationVisitor visitor; 2352 FlagsSerializationVisitor visitor;
2291 frame.Visit(&visitor); 2353 frame.Visit(&visitor);
2292 return visitor.flags(); 2354 return visitor.flags();
2293 } 2355 }
2294 2356
2357 bool SpdyFramer::SerializeData(const SpdyDataIR& data_ir,
2358 ZeroCopyOutputBuffer* output) const {
2359 uint8_t flags = DATA_FLAG_NONE;
2360 int num_padding_fields = 0;
2361 size_t size_with_padding = 0;
2362 SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields,
2363 &size_with_padding);
2364 SpdyFrameBuilder builder(size_with_padding, output);
2365
2366 bool ok = builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id());
2367
2368 if (data_ir.padded()) {
2369 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2370 }
2371
2372 ok = ok && builder.WriteBytes(data_ir.data(), data_ir.data_len());
2373 if (data_ir.padding_payload_len() > 0) {
2374 string padding;
2375 padding = string(data_ir.padding_payload_len(), 0);
2376 ok = ok && builder.WriteBytes(padding.data(), padding.length());
2377 }
2378 DCHECK_EQ(size_with_padding, builder.length());
2379 return ok;
2380 }
2381
2382 bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField(
2383 const SpdyDataIR& data_ir,
2384 ZeroCopyOutputBuffer* output) const {
2385 uint8_t flags = DATA_FLAG_NONE;
2386 size_t frame_size = 0;
2387 size_t num_padding_fields = 0;
2388 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper(
2389 data_ir, &flags, &frame_size, &num_padding_fields);
2390
2391 SpdyFrameBuilder builder(frame_size, output);
2392 bool ok = true;
2393 if (!skip_rewritelength_) {
2394 ok = builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id());
2395 if (data_ir.padded()) {
2396 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2397 }
2398 ok = ok && builder.OverwriteLength(*this,
2399 num_padding_fields + data_ir.data_len() +
2400 data_ir.padding_payload_len());
2401 } else {
2402 ok = ok && builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id(),
2403 num_padding_fields + data_ir.data_len() +
2404 data_ir.padding_payload_len());
2405 if (data_ir.padded()) {
2406 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff);
2407 }
2408 }
2409 DCHECK_EQ(frame_size, builder.length());
2410 return ok;
2411 }
2412
2413 bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream,
2414 ZeroCopyOutputBuffer* output) const {
2415 size_t expected_length = GetRstStreamSize();
2416 SpdyFrameBuilder builder(expected_length, output);
2417 bool ok = builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id());
2418 ok = ok && builder.WriteUInt32(rst_stream.error_code());
2419
2420 DCHECK_EQ(expected_length, builder.length());
2421 return ok;
2422 }
2423
2424 bool SpdyFramer::SerializeSettings(const SpdySettingsIR& settings,
2425 ZeroCopyOutputBuffer* output) const {
2426 uint8_t flags = 0;
2427 // Size, in bytes, of this SETTINGS frame.
2428 size_t size = 0;
2429 const SettingsMap* values = &(settings.values());
2430 SerializeSettingsBuilderHelper(settings, &flags, values, &size);
2431 SpdyFrameBuilder builder(size, output);
2432 bool ok = builder.BeginNewFrame(*this, SETTINGS, flags, 0);
2433
2434 // If this is an ACK, payload should be empty.
2435 if (settings.is_ack()) {
2436 return ok;
2437 }
2438
2439 DCHECK_EQ(GetSettingsMinimumSize(), builder.length());
2440 for (SettingsMap::const_iterator it = values->begin(); it != values->end();
2441 ++it) {
2442 int setting_id = it->first;
2443 DCHECK_GE(setting_id, 0);
2444 ok = ok && builder.WriteUInt16(static_cast<uint16_t>(setting_id)) &&
2445 builder.WriteUInt32(it->second);
2446 }
2447 DCHECK_EQ(size, builder.length());
2448 return ok;
2449 }
2450
2451 bool SpdyFramer::SerializePing(const SpdyPingIR& ping,
2452 ZeroCopyOutputBuffer* output) const {
2453 SpdyFrameBuilder builder(GetPingSize(), output);
2454 uint8_t flags = 0;
2455 if (ping.is_ack()) {
2456 flags |= PING_FLAG_ACK;
2457 }
2458 bool ok = builder.BeginNewFrame(*this, PING, flags, 0);
2459 ok = ok && builder.WriteUInt64(ping.id());
2460 DCHECK_EQ(GetPingSize(), builder.length());
2461 return ok;
2462 }
2463
2464 bool SpdyFramer::SerializeGoAway(const SpdyGoAwayIR& goaway,
2465 ZeroCopyOutputBuffer* output) const {
2466 // Compute the output buffer size, take opaque data into account.
2467 size_t expected_length = GetGoAwayMinimumSize();
2468 expected_length += goaway.description().size();
2469 SpdyFrameBuilder builder(expected_length, output);
2470
2471 // Serialize the GOAWAY frame.
2472 bool ok = builder.BeginNewFrame(*this, GOAWAY, 0, 0);
2473
2474 // GOAWAY frames specify the last good stream id.
2475 ok = ok && builder.WriteUInt32(goaway.last_good_stream_id()) &&
2476 // GOAWAY frames also specify the error status code.
2477 builder.WriteUInt32(goaway.error_code());
2478
2479 // GOAWAY frames may also specify opaque data.
2480 if (!goaway.description().empty()) {
2481 ok = ok && builder.WriteBytes(goaway.description().data(),
2482 goaway.description().size());
2483 }
2484
2485 DCHECK_EQ(expected_length, builder.length());
2486 return ok;
2487 }
2488
2489 bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers,
2490 ZeroCopyOutputBuffer* output) {
2491 uint8_t flags = 0;
2492 // The size of this frame, including padding (if there is any) and
2493 // variable-length header block.
2494 size_t size = 0;
2495 string hpack_encoding;
2496 int weight = 0;
2497 size_t length_field = 0;
2498 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding,
2499 &weight, &length_field);
2500
2501 bool ok = true;
2502 SpdyFrameBuilder builder(size, output);
2503 if (!skip_rewritelength_) {
2504 ok = builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id());
2505 } else {
2506 ok = ok && builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id(),
2507 length_field);
2508 }
2509 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2510
2511 int padding_payload_len = 0;
2512 if (headers.padded()) {
2513 ok = ok && builder.WriteUInt8(headers.padding_payload_len());
2514 padding_payload_len = headers.padding_payload_len();
2515 }
2516 if (headers.has_priority()) {
2517 ok = ok &&
2518 builder.WriteUInt32(PackStreamDependencyValues(
2519 headers.exclusive(), headers.parent_stream_id())) &&
2520 // Per RFC 7540 section 6.3, serialized weight value is weight - 1.
2521 builder.WriteUInt8(weight - 1);
2522 }
2523 ok = ok && WritePayloadWithContinuation(&builder, hpack_encoding,
2524 headers.stream_id(), HEADERS,
2525 padding_payload_len);
2526
2527 if (debug_visitor_) {
2528 // HTTP2 uses HPACK for header compression. However, continue to
2529 // use GetSerializedLength() for an apples-to-apples comparision of
2530 // compression performance between HPACK and SPDY w/ deflate.
2531 const size_t payload_len = GetSerializedLength(&(headers.header_block()));
2532 debug_visitor_->OnSendCompressedFrame(headers.stream_id(), HEADERS,
2533 payload_len, builder.length());
2534 }
2535
2536 return ok;
2537 }
2538
2539 bool SpdyFramer::SerializeWindowUpdate(const SpdyWindowUpdateIR& window_update,
2540 ZeroCopyOutputBuffer* output) const {
2541 SpdyFrameBuilder builder(GetWindowUpdateSize(), output);
2542 bool ok = builder.BeginNewFrame(*this, WINDOW_UPDATE, kNoFlags,
2543 window_update.stream_id());
2544 ok = ok && builder.WriteUInt32(window_update.delta());
2545 DCHECK_EQ(GetWindowUpdateSize(), builder.length());
2546 return ok;
2547 }
2548
2549 bool SpdyFramer::SerializeBlocked(const SpdyBlockedIR& blocked,
2550 ZeroCopyOutputBuffer* output) const {
2551 SpdyFrameBuilder builder(GetBlockedSize(), output);
2552 return builder.BeginNewFrame(*this, BLOCKED, kNoFlags, blocked.stream_id());
2553 }
2554
2555 bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise,
2556 ZeroCopyOutputBuffer* output) {
2557 uint8_t flags = 0;
2558 size_t size = 0;
2559 string hpack_encoding;
2560 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding,
2561 &size);
2562
2563 bool ok = true;
2564 SpdyFrameBuilder builder(size, output);
2565 if (!skip_rewritelength_) {
2566 ok = builder.BeginNewFrame(*this, PUSH_PROMISE, flags,
2567 push_promise.stream_id());
2568 } else {
2569 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize();
2570 ok = builder.BeginNewFrame(*this, PUSH_PROMISE, flags,
2571 push_promise.stream_id(), length);
2572 }
2573
2574 int padding_payload_len = 0;
2575 if (push_promise.padded()) {
2576 ok = ok && builder.WriteUInt8(push_promise.padding_payload_len()) &&
2577 builder.WriteUInt32(push_promise.promised_stream_id());
2578 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize,
2579 builder.length());
2580
2581 padding_payload_len = push_promise.padding_payload_len();
2582 } else {
2583 ok = ok && builder.WriteUInt32(push_promise.promised_stream_id());
2584 DCHECK_EQ(GetPushPromiseMinimumSize(), builder.length());
2585 }
2586
2587 ok = ok && WritePayloadWithContinuation(&builder, hpack_encoding,
2588 push_promise.stream_id(),
2589 PUSH_PROMISE, padding_payload_len);
2590
2591 if (debug_visitor_) {
2592 // HTTP2 uses HPACK for header compression. However, continue to
2593 // use GetSerializedLength() for an apples-to-apples comparision of
2594 // compression performance between HPACK and SPDY w/ deflate.
2595 const size_t payload_len =
2596 GetSerializedLength(&(push_promise.header_block()));
2597 debug_visitor_->OnSendCompressedFrame(
2598 push_promise.stream_id(), PUSH_PROMISE, payload_len, builder.length());
2599 }
2600
2601 return ok;
2602 }
2603
2604 bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation,
2605 ZeroCopyOutputBuffer* output) const {
2606 const string& encoding = continuation.encoding();
2607 size_t frame_size = GetContinuationMinimumSize() + encoding.size();
2608 SpdyFrameBuilder builder(frame_size, output);
2609 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0;
2610 bool ok = builder.BeginNewFrame(*this, CONTINUATION, flags,
2611 continuation.stream_id());
2612 DCHECK_EQ(GetFrameHeaderSize(), builder.length());
2613
2614 ok = ok && builder.WriteBytes(encoding.data(), encoding.size());
2615 return ok;
2616 }
2617
2618 bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir,
2619 ZeroCopyOutputBuffer* output) {
2620 string value;
2621 size_t size = 0;
2622 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size);
2623 SpdyFrameBuilder builder(size, output);
2624 bool ok =
2625 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc_ir.stream_id()) &&
2626 builder.WriteUInt16(altsvc_ir.origin().length()) &&
2627 builder.WriteBytes(altsvc_ir.origin().data(),
2628 altsvc_ir.origin().length()) &&
2629 builder.WriteBytes(value.data(), value.length());
2630 DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
2631 return ok;
2632 }
2633
2634 bool SpdyFramer::SerializePriority(const SpdyPriorityIR& priority,
2635 ZeroCopyOutputBuffer* output) const {
2636 size_t size = GetPrioritySize();
2637
2638 SpdyFrameBuilder builder(size, output);
2639 bool ok =
2640 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id());
2641 ok = ok &&
2642 builder.WriteUInt32(PackStreamDependencyValues(
2643 priority.exclusive(), priority.parent_stream_id())) &&
2644 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1.
2645 builder.WriteUInt8(priority.weight() - 1);
2646 DCHECK_EQ(GetPrioritySize(), builder.length());
2647 return ok;
2648 }
2649
2650 namespace {
2651
2652 class FrameSerializationVisitorWithOutput : public SpdyFrameVisitor {
2653 public:
2654 explicit FrameSerializationVisitorWithOutput(SpdyFramer* framer,
2655 ZeroCopyOutputBuffer* output)
2656 : framer_(framer), output_(output), result_(false) {}
2657 ~FrameSerializationVisitorWithOutput() override {}
2658
2659 bool Result() { return result_; }
2660
2661 void VisitData(const SpdyDataIR& data) override {
2662 result_ = framer_->SerializeData(data, output_);
2663 }
2664 void VisitRstStream(const SpdyRstStreamIR& rst_stream) override {
2665 result_ = framer_->SerializeRstStream(rst_stream, output_);
2666 }
2667 void VisitSettings(const SpdySettingsIR& settings) override {
2668 result_ = framer_->SerializeSettings(settings, output_);
2669 }
2670 void VisitPing(const SpdyPingIR& ping) override {
2671 result_ = framer_->SerializePing(ping, output_);
2672 }
2673 void VisitGoAway(const SpdyGoAwayIR& goaway) override {
2674 result_ = framer_->SerializeGoAway(goaway, output_);
2675 }
2676 void VisitHeaders(const SpdyHeadersIR& headers) override {
2677 result_ = framer_->SerializeHeaders(headers, output_);
2678 }
2679 void VisitWindowUpdate(const SpdyWindowUpdateIR& window_update) override {
2680 result_ = framer_->SerializeWindowUpdate(window_update, output_);
2681 }
2682 void VisitBlocked(const SpdyBlockedIR& blocked) override {
2683 result_ = framer_->SerializeBlocked(blocked, output_);
2684 }
2685 void VisitPushPromise(const SpdyPushPromiseIR& push_promise) override {
2686 result_ = framer_->SerializePushPromise(push_promise, output_);
2687 }
2688 void VisitContinuation(const SpdyContinuationIR& continuation) override {
2689 result_ = framer_->SerializeContinuation(continuation, output_);
2690 }
2691 void VisitAltSvc(const SpdyAltSvcIR& altsvc) override {
2692 result_ = framer_->SerializeAltSvc(altsvc, output_);
2693 }
2694 void VisitPriority(const SpdyPriorityIR& priority) override {
2695 result_ = framer_->SerializePriority(priority, output_);
2696 }
2697
2698 private:
2699 SpdyFramer* framer_;
2700 ZeroCopyOutputBuffer* output_;
2701 bool result_;
2702 };
2703
2704 } // namespace
2705
2706 bool SpdyFramer::SerializeFrame(const SpdyFrameIR& frame,
2707 ZeroCopyOutputBuffer* output) {
2708 FrameSerializationVisitorWithOutput visitor(this, output);
2709 frame.Visit(&visitor);
2710 return visitor.Result();
2711 }
2712
2295 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) { 2713 size_t SpdyFramer::GetNumberRequiredContinuationFrames(size_t size) {
2296 DCHECK_GT(size, kMaxControlFrameSize); 2714 DCHECK_GT(size, kMaxControlFrameSize);
2297 size_t overflow = size - kMaxControlFrameSize; 2715 size_t overflow = size - kMaxControlFrameSize;
2298 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize(); 2716 size_t payload_size = kMaxControlFrameSize - GetContinuationMinimumSize();
2299 // This is ceiling(overflow/payload_size) using integer arithmetics. 2717 // This is ceiling(overflow/payload_size) using integer arithmetics.
2300 return (overflow - 1) / payload_size + 1; 2718 return (overflow - 1) / payload_size + 1;
2301 } 2719 }
2302 2720
2303 size_t SpdyFramer::GetHeaderFrameSizeSansBlock( 2721 size_t SpdyFramer::GetHeaderFrameSizeSansBlock(
2304 const SpdyHeadersIR& header_ir) const { 2722 const SpdyHeadersIR& header_ir) const {
(...skipping 22 matching lines...) Expand all
2327 } 2745 }
2328 if (header_ir.padded()) { 2746 if (header_ir.padded()) {
2329 flags |= HEADERS_FLAG_PADDED; 2747 flags |= HEADERS_FLAG_PADDED;
2330 } 2748 }
2331 if (header_ir.has_priority()) { 2749 if (header_ir.has_priority()) {
2332 flags |= HEADERS_FLAG_PRIORITY; 2750 flags |= HEADERS_FLAG_PRIORITY;
2333 } 2751 }
2334 return flags; 2752 return flags;
2335 } 2753 }
2336 2754
2337 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, 2755 bool SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2338 const string& hpack_encoding, 2756 const string& hpack_encoding,
2339 SpdyStreamId stream_id, 2757 SpdyStreamId stream_id,
2340 SpdyFrameType type, 2758 SpdyFrameType type,
2341 int padding_payload_len) { 2759 int padding_payload_len) {
2342 uint8_t end_flag = 0; 2760 uint8_t end_flag = 0;
2343 uint8_t flags = 0; 2761 uint8_t flags = 0;
2344 if (type == HEADERS) { 2762 if (type == HEADERS) {
2345 end_flag = HEADERS_FLAG_END_HEADERS; 2763 end_flag = HEADERS_FLAG_END_HEADERS;
2346 } else if (type == PUSH_PROMISE) { 2764 } else if (type == PUSH_PROMISE) {
2347 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2765 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2348 } else { 2766 } else {
2349 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " 2767 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
2350 << FrameTypeToString(type); 2768 << FrameTypeToString(type);
2351 } 2769 }
2352 2770
2353 // Write all the padding payload and as much of the data payload as possible 2771 // Write all the padding payload and as much of the data payload as possible
2354 // into the initial frame. 2772 // into the initial frame.
2355 size_t bytes_remaining = 0; 2773 size_t bytes_remaining = 0;
2356 bytes_remaining = 2774 bytes_remaining =
2357 hpack_encoding.size() - 2775 hpack_encoding.size() -
2358 std::min(hpack_encoding.size(), 2776 std::min(hpack_encoding.size(),
2359 kMaxControlFrameSize - builder->length() - padding_payload_len); 2777 kMaxControlFrameSize - builder->length() - padding_payload_len);
2360 builder->WriteBytes(&hpack_encoding[0], 2778 bool ret = builder->WriteBytes(&hpack_encoding[0],
2361 hpack_encoding.size() - bytes_remaining); 2779 hpack_encoding.size() - bytes_remaining);
2362 if (padding_payload_len > 0) { 2780 if (padding_payload_len > 0) {
2363 string padding = string(padding_payload_len, 0); 2781 string padding = string(padding_payload_len, 0);
2364 builder->WriteBytes(padding.data(), padding.length()); 2782 ret &= builder->WriteBytes(padding.data(), padding.length());
2365 } 2783 }
2366 if (bytes_remaining > 0 && !skip_rewritelength_) { 2784 if (bytes_remaining > 0 && !skip_rewritelength_) {
2367 builder->OverwriteLength(*this, 2785 ret &= builder->OverwriteLength(
2368 kMaxControlFrameSize - GetFrameHeaderSize()); 2786 *this, kMaxControlFrameSize - GetFrameHeaderSize());
2369 } 2787 }
2370 2788
2371 // Tack on CONTINUATION frames for the overflow. 2789 // Tack on CONTINUATION frames for the overflow.
2372 while (bytes_remaining > 0) { 2790 while (bytes_remaining > 0 && ret) {
2373 size_t bytes_to_write = std::min( 2791 size_t bytes_to_write = std::min(
2374 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); 2792 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize());
2375 // Write CONTINUATION frame prefix. 2793 // Write CONTINUATION frame prefix.
2376 if (bytes_remaining == bytes_to_write) { 2794 if (bytes_remaining == bytes_to_write) {
2377 flags |= end_flag; 2795 flags |= end_flag;
2378 } 2796 }
2379 if (!skip_rewritelength_) { 2797 if (!skip_rewritelength_) {
2380 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); 2798 ret &= builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id);
2381 } else { 2799 } else {
2382 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id, 2800 ret &= builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id,
2383 bytes_to_write); 2801 bytes_to_write);
2384 } 2802 }
2385 // Write payload fragment. 2803 // Write payload fragment.
2386 builder->WriteBytes( 2804 ret &= builder->WriteBytes(
2387 &hpack_encoding[hpack_encoding.size() - bytes_remaining], 2805 &hpack_encoding[hpack_encoding.size() - bytes_remaining],
2388 bytes_to_write); 2806 bytes_to_write);
2389 bytes_remaining -= bytes_to_write; 2807 bytes_remaining -= bytes_to_write;
2390 } 2808 }
2809 return ret;
2391 } 2810 }
2392 2811
2393 HpackEncoder* SpdyFramer::GetHpackEncoder() { 2812 HpackEncoder* SpdyFramer::GetHpackEncoder() {
2394 if (hpack_encoder_.get() == nullptr) { 2813 if (hpack_encoder_.get() == nullptr) {
2395 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable())); 2814 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
2396 if (!compression_enabled()) { 2815 if (!compression_enabled()) {
2397 hpack_encoder_->DisableCompression(); 2816 hpack_encoder_->DisableCompression();
2398 } 2817 }
2399 } 2818 }
2400 return hpack_encoder_.get(); 2819 return hpack_encoder_.get();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
2461 builder->WriteUInt32(header_block.size()); 2880 builder->WriteUInt32(header_block.size());
2462 2881
2463 // Serialize each header. 2882 // Serialize each header.
2464 for (const auto& header : header_block) { 2883 for (const auto& header : header_block) {
2465 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); 2884 builder->WriteStringPiece32(base::ToLowerASCII(header.first));
2466 builder->WriteStringPiece32(header.second); 2885 builder->WriteStringPiece32(header.second);
2467 } 2886 }
2468 } 2887 }
2469 2888
2470 } // namespace net 2889 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698