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 #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> |
11 #include <ios> | 11 #include <ios> |
12 #include <iterator> | 12 #include <iterator> |
13 #include <list> | 13 #include <list> |
14 #include <memory> | 14 #include <memory> |
15 #include <new> | 15 #include <new> |
16 #include <string> | |
17 #include <vector> | 16 #include <vector> |
18 | 17 |
19 #include "base/lazy_instance.h" | 18 #include "base/lazy_instance.h" |
20 #include "base/logging.h" | 19 #include "base/logging.h" |
21 #include "base/memory/ptr_util.h" | 20 #include "base/memory/ptr_util.h" |
22 #include "base/metrics/histogram_macros.h" | 21 #include "base/metrics/histogram_macros.h" |
23 #include "base/strings/string_util.h" | 22 #include "base/strings/string_util.h" |
24 #include "net/quic/core/quic_flags.h" | 23 #include "net/quic/core/quic_flags.h" |
25 #include "net/spdy/hpack/hpack_constants.h" | 24 #include "net/spdy/hpack/hpack_constants.h" |
26 #include "net/spdy/hpack/hpack_decoder.h" | 25 #include "net/spdy/hpack/hpack_decoder.h" |
27 #include "net/spdy/hpack/hpack_decoder3.h" | 26 #include "net/spdy/hpack/hpack_decoder3.h" |
28 #include "net/spdy/http2_frame_decoder_adapter.h" | 27 #include "net/spdy/http2_frame_decoder_adapter.h" |
29 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" | 28 #include "net/spdy/platform/api/spdy_estimate_memory_usage.h" |
30 #include "net/spdy/platform/api/spdy_string_utils.h" | 29 #include "net/spdy/platform/api/spdy_string_utils.h" |
31 #include "net/spdy/spdy_bitmasks.h" | 30 #include "net/spdy/spdy_bitmasks.h" |
32 #include "net/spdy/spdy_bug_tracker.h" | 31 #include "net/spdy/spdy_bug_tracker.h" |
33 #include "net/spdy/spdy_flags.h" | 32 #include "net/spdy/spdy_flags.h" |
34 #include "net/spdy/spdy_frame_builder.h" | 33 #include "net/spdy/spdy_frame_builder.h" |
35 #include "net/spdy/spdy_frame_reader.h" | 34 #include "net/spdy/spdy_frame_reader.h" |
36 #include "net/spdy/spdy_framer_decoder_adapter.h" | 35 #include "net/spdy/spdy_framer_decoder_adapter.h" |
37 | 36 |
38 using std::string; | |
39 using std::vector; | 37 using std::vector; |
40 | 38 |
41 namespace net { | 39 namespace net { |
42 | 40 |
43 namespace { | 41 namespace { |
44 | 42 |
45 // Pack parent stream ID and exclusive flag into the format used by HTTP/2 | 43 // Pack parent stream ID and exclusive flag into the format used by HTTP/2 |
46 // headers and priority frames. | 44 // headers and priority frames. |
47 uint32_t PackStreamDependencyValues(bool exclusive, | 45 uint32_t PackStreamDependencyValues(bool exclusive, |
48 SpdyStreamId parent_stream_id) { | 46 SpdyStreamId parent_stream_id) { |
(...skipping 1581 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1630 return false; | 1628 return false; |
1631 } | 1629 } |
1632 const char* begin = temp.data(); | 1630 const char* begin = temp.data(); |
1633 const char* end = begin; | 1631 const char* end = begin; |
1634 std::advance(end, temp.size()); | 1632 std::advance(end, temp.size()); |
1635 if (std::any_of(begin, end, isupper)) { | 1633 if (std::any_of(begin, end, isupper)) { |
1636 DVLOG(1) << "Malformed header: Header name " << temp | 1634 DVLOG(1) << "Malformed header: Header name " << temp |
1637 << " contains upper-case characters."; | 1635 << " contains upper-case characters."; |
1638 return false; | 1636 return false; |
1639 } | 1637 } |
1640 std::string name(temp); | 1638 SpdyString name(temp); |
1641 | 1639 |
1642 // Read header value. | 1640 // Read header value. |
1643 if (!reader.ReadStringPiece32(&temp)) { | 1641 if (!reader.ReadStringPiece32(&temp)) { |
1644 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " | 1642 DVLOG(1) << "Unable to read header value (" << index + 1 << " of " |
1645 << num_headers << ")."; | 1643 << num_headers << ")."; |
1646 return false; | 1644 return false; |
1647 } | 1645 } |
1648 std::string value(temp); | 1646 SpdyString value(temp); |
1649 | 1647 |
1650 // Ensure no duplicates. | 1648 // Ensure no duplicates. |
1651 if (block->find(name) != block->end()) { | 1649 if (block->find(name) != block->end()) { |
1652 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " | 1650 DVLOG(1) << "Duplicate header '" << name << "' (" << index + 1 << " of " |
1653 << num_headers << ")."; | 1651 << num_headers << ")."; |
1654 return false; | 1652 return false; |
1655 } | 1653 } |
1656 | 1654 |
1657 // Store header. | 1655 // Store header. |
1658 (*block)[name] = value; | 1656 (*block)[name] = value; |
(...skipping 25 matching lines...) Expand all Loading... |
1684 SpdySerializedFrame SpdyFramer::SpdyHeaderFrameIterator::NextFrame() { | 1682 SpdySerializedFrame SpdyFramer::SpdyHeaderFrameIterator::NextFrame() { |
1685 if (!has_next_frame_) { | 1683 if (!has_next_frame_) { |
1686 SPDY_BUG << "SpdyFramer::SpdyHeaderFrameIterator::NextFrame called without " | 1684 SPDY_BUG << "SpdyFramer::SpdyHeaderFrameIterator::NextFrame called without " |
1687 << "a next frame."; | 1685 << "a next frame."; |
1688 return SpdySerializedFrame(); | 1686 return SpdySerializedFrame(); |
1689 } | 1687 } |
1690 | 1688 |
1691 size_t size_without_block = | 1689 size_t size_without_block = |
1692 is_first_frame_ ? framer_->GetHeaderFrameSizeSansBlock(*headers_ir_) | 1690 is_first_frame_ ? framer_->GetHeaderFrameSizeSansBlock(*headers_ir_) |
1693 : framer_->GetContinuationMinimumSize(); | 1691 : framer_->GetContinuationMinimumSize(); |
1694 auto encoding = base::MakeUnique<string>(); | 1692 auto encoding = base::MakeUnique<SpdyString>(); |
1695 encoder_->Next(kMaxControlFrameSize - size_without_block, encoding.get()); | 1693 encoder_->Next(kMaxControlFrameSize - size_without_block, encoding.get()); |
1696 has_next_frame_ = encoder_->HasNext(); | 1694 has_next_frame_ = encoder_->HasNext(); |
1697 | 1695 |
1698 if (framer_->debug_visitor_ != nullptr) { | 1696 if (framer_->debug_visitor_ != nullptr) { |
1699 debug_total_size_ += size_without_block; | 1697 debug_total_size_ += size_without_block; |
1700 debug_total_size_ += encoding->size(); | 1698 debug_total_size_ += encoding->size(); |
1701 if (!has_next_frame_) { | 1699 if (!has_next_frame_) { |
1702 // TODO(birenroy) are these (here and below) still necessary? | 1700 // TODO(birenroy) are these (here and below) still necessary? |
1703 // HTTP2 uses HPACK for header compression. However, continue to | 1701 // HTTP2 uses HPACK for header compression. However, continue to |
1704 // use GetSerializedLength() for an apples-to-apples comparision of | 1702 // use GetSerializedLength() for an apples-to-apples comparision of |
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1748 SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields, | 1746 SerializeDataBuilderHelper(data_ir, &flags, &num_padding_fields, |
1749 &size_with_padding); | 1747 &size_with_padding); |
1750 | 1748 |
1751 SpdyFrameBuilder builder(size_with_padding); | 1749 SpdyFrameBuilder builder(size_with_padding); |
1752 builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, data_ir.stream_id()); | 1750 builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, data_ir.stream_id()); |
1753 if (data_ir.padded()) { | 1751 if (data_ir.padded()) { |
1754 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 1752 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
1755 } | 1753 } |
1756 builder.WriteBytes(data_ir.data(), data_ir.data_len()); | 1754 builder.WriteBytes(data_ir.data(), data_ir.data_len()); |
1757 if (data_ir.padding_payload_len() > 0) { | 1755 if (data_ir.padding_payload_len() > 0) { |
1758 string padding(data_ir.padding_payload_len(), 0); | 1756 SpdyString padding(data_ir.padding_payload_len(), 0); |
1759 builder.WriteBytes(padding.data(), padding.length()); | 1757 builder.WriteBytes(padding.data(), padding.length()); |
1760 } | 1758 } |
1761 DCHECK_EQ(size_with_padding, builder.length()); | 1759 DCHECK_EQ(size_with_padding, builder.length()); |
1762 return builder.take(); | 1760 return builder.take(); |
1763 } | 1761 } |
1764 | 1762 |
1765 void SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( | 1763 void SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( |
1766 const SpdyDataIR& data_ir, | 1764 const SpdyDataIR& data_ir, |
1767 uint8_t* flags, | 1765 uint8_t* flags, |
1768 size_t* frame_size, | 1766 size_t* frame_size, |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1896 goaway.description().size()); | 1894 goaway.description().size()); |
1897 } | 1895 } |
1898 | 1896 |
1899 DCHECK_EQ(expected_length, builder.length()); | 1897 DCHECK_EQ(expected_length, builder.length()); |
1900 return builder.take(); | 1898 return builder.take(); |
1901 } | 1899 } |
1902 | 1900 |
1903 void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers, | 1901 void SpdyFramer::SerializeHeadersBuilderHelper(const SpdyHeadersIR& headers, |
1904 uint8_t* flags, | 1902 uint8_t* flags, |
1905 size_t* size, | 1903 size_t* size, |
1906 string* hpack_encoding, | 1904 SpdyString* hpack_encoding, |
1907 int* weight, | 1905 int* weight, |
1908 size_t* length_field) { | 1906 size_t* length_field) { |
1909 if (headers.fin()) { | 1907 if (headers.fin()) { |
1910 *flags = *flags | CONTROL_FLAG_FIN; | 1908 *flags = *flags | CONTROL_FLAG_FIN; |
1911 } | 1909 } |
1912 // This will get overwritten if we overflow into a CONTINUATION frame. | 1910 // This will get overwritten if we overflow into a CONTINUATION frame. |
1913 *flags = *flags | HEADERS_FLAG_END_HEADERS; | 1911 *flags = *flags | HEADERS_FLAG_END_HEADERS; |
1914 if (headers.has_priority()) { | 1912 if (headers.has_priority()) { |
1915 *flags = *flags | HEADERS_FLAG_PRIORITY; | 1913 *flags = *flags | HEADERS_FLAG_PRIORITY; |
1916 } | 1914 } |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1952 // necessary. | 1950 // necessary. |
1953 *length_field = | 1951 *length_field = |
1954 std::min(*length_field, kMaxControlFrameSize - GetFrameHeaderSize()); | 1952 std::min(*length_field, kMaxControlFrameSize - GetFrameHeaderSize()); |
1955 } | 1953 } |
1956 | 1954 |
1957 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { | 1955 SpdySerializedFrame SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers) { |
1958 uint8_t flags = 0; | 1956 uint8_t flags = 0; |
1959 // The size of this frame, including padding (if there is any) and | 1957 // The size of this frame, including padding (if there is any) and |
1960 // variable-length header block. | 1958 // variable-length header block. |
1961 size_t size = 0; | 1959 size_t size = 0; |
1962 string hpack_encoding; | 1960 SpdyString hpack_encoding; |
1963 int weight = 0; | 1961 int weight = 0; |
1964 size_t length_field = 0; | 1962 size_t length_field = 0; |
1965 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, | 1963 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, |
1966 &weight, &length_field); | 1964 &weight, &length_field); |
1967 | 1965 |
1968 SpdyFrameBuilder builder(size); | 1966 SpdyFrameBuilder builder(size); |
1969 | 1967 |
1970 if (!skip_rewritelength_) { | 1968 if (!skip_rewritelength_) { |
1971 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | 1969 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, |
1972 headers.stream_id()); | 1970 headers.stream_id()); |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2009 builder.BeginNewFrame(*this, SpdyFrameType::WINDOW_UPDATE, kNoFlags, | 2007 builder.BeginNewFrame(*this, SpdyFrameType::WINDOW_UPDATE, kNoFlags, |
2010 window_update.stream_id()); | 2008 window_update.stream_id()); |
2011 builder.WriteUInt32(window_update.delta()); | 2009 builder.WriteUInt32(window_update.delta()); |
2012 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2010 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
2013 return builder.take(); | 2011 return builder.take(); |
2014 } | 2012 } |
2015 | 2013 |
2016 void SpdyFramer::SerializePushPromiseBuilderHelper( | 2014 void SpdyFramer::SerializePushPromiseBuilderHelper( |
2017 const SpdyPushPromiseIR& push_promise, | 2015 const SpdyPushPromiseIR& push_promise, |
2018 uint8_t* flags, | 2016 uint8_t* flags, |
2019 string* hpack_encoding, | 2017 SpdyString* hpack_encoding, |
2020 size_t* size) { | 2018 size_t* size) { |
2021 *flags = 0; | 2019 *flags = 0; |
2022 // This will get overwritten if we overflow into a CONTINUATION frame. | 2020 // This will get overwritten if we overflow into a CONTINUATION frame. |
2023 *flags = *flags | PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2021 *flags = *flags | PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2024 // The size of this frame, including variable-length name-value block. | 2022 // The size of this frame, including variable-length name-value block. |
2025 *size = GetPushPromiseMinimumSize(); | 2023 *size = GetPushPromiseMinimumSize(); |
2026 | 2024 |
2027 if (push_promise.padded()) { | 2025 if (push_promise.padded()) { |
2028 *flags = *flags | PUSH_PROMISE_FLAG_PADDED; | 2026 *flags = *flags | PUSH_PROMISE_FLAG_PADDED; |
2029 *size = *size + kPadLengthFieldSize; | 2027 *size = *size + kPadLengthFieldSize; |
2030 *size = *size + push_promise.padding_payload_len(); | 2028 *size = *size + push_promise.padding_payload_len(); |
2031 } | 2029 } |
2032 | 2030 |
2033 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), | 2031 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), |
2034 hpack_encoding); | 2032 hpack_encoding); |
2035 *size = *size + hpack_encoding->size(); | 2033 *size = *size + hpack_encoding->size(); |
2036 if (*size > kMaxControlFrameSize) { | 2034 if (*size > kMaxControlFrameSize) { |
2037 *size = *size + GetNumberRequiredContinuationFrames(*size) * | 2035 *size = *size + GetNumberRequiredContinuationFrames(*size) * |
2038 GetContinuationMinimumSize(); | 2036 GetContinuationMinimumSize(); |
2039 *flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2037 *flags = *flags & ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2040 } | 2038 } |
2041 } | 2039 } |
2042 | 2040 |
2043 SpdySerializedFrame SpdyFramer::SerializePushPromise( | 2041 SpdySerializedFrame SpdyFramer::SerializePushPromise( |
2044 const SpdyPushPromiseIR& push_promise) { | 2042 const SpdyPushPromiseIR& push_promise) { |
2045 uint8_t flags = 0; | 2043 uint8_t flags = 0; |
2046 size_t size = 0; | 2044 size_t size = 0; |
2047 string hpack_encoding; | 2045 SpdyString hpack_encoding; |
2048 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, | 2046 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, |
2049 &size); | 2047 &size); |
2050 | 2048 |
2051 SpdyFrameBuilder builder(size); | 2049 SpdyFrameBuilder builder(size); |
2052 if (!skip_rewritelength_) { | 2050 if (!skip_rewritelength_) { |
2053 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | 2051 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, |
2054 push_promise.stream_id()); | 2052 push_promise.stream_id()); |
2055 } else { | 2053 } else { |
2056 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); | 2054 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); |
2057 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | 2055 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, |
(...skipping 25 matching lines...) Expand all Loading... |
2083 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2081 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), |
2084 SpdyFrameType::PUSH_PROMISE, | 2082 SpdyFrameType::PUSH_PROMISE, |
2085 payload_len, builder.length()); | 2083 payload_len, builder.length()); |
2086 } | 2084 } |
2087 | 2085 |
2088 return builder.take(); | 2086 return builder.take(); |
2089 } | 2087 } |
2090 | 2088 |
2091 SpdySerializedFrame SpdyFramer::SerializeHeadersGivenEncoding( | 2089 SpdySerializedFrame SpdyFramer::SerializeHeadersGivenEncoding( |
2092 const SpdyHeadersIR& headers, | 2090 const SpdyHeadersIR& headers, |
2093 const string& encoding) const { | 2091 const SpdyString& encoding) const { |
2094 size_t frame_size = GetHeaderFrameSizeSansBlock(headers) + encoding.size(); | 2092 size_t frame_size = GetHeaderFrameSizeSansBlock(headers) + encoding.size(); |
2095 SpdyFrameBuilder builder(frame_size); | 2093 SpdyFrameBuilder builder(frame_size); |
2096 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, | 2094 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, |
2097 SerializeHeaderFrameFlags(headers), | 2095 SerializeHeaderFrameFlags(headers), |
2098 headers.stream_id()); | 2096 headers.stream_id()); |
2099 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); | 2097 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); |
2100 | 2098 |
2101 if (headers.padded()) { | 2099 if (headers.padded()) { |
2102 builder.WriteUInt8(headers.padding_payload_len()); | 2100 builder.WriteUInt8(headers.padding_payload_len()); |
2103 } | 2101 } |
2104 | 2102 |
2105 if (headers.has_priority()) { | 2103 if (headers.has_priority()) { |
2106 int weight = ClampHttp2Weight(headers.weight()); | 2104 int weight = ClampHttp2Weight(headers.weight()); |
2107 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), | 2105 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
2108 headers.parent_stream_id())); | 2106 headers.parent_stream_id())); |
2109 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. | 2107 // Per RFC 7540 section 6.3, serialized weight value is actual value - 1. |
2110 builder.WriteUInt8(weight - 1); | 2108 builder.WriteUInt8(weight - 1); |
2111 } | 2109 } |
2112 | 2110 |
2113 builder.WriteBytes(&encoding[0], encoding.size()); | 2111 builder.WriteBytes(&encoding[0], encoding.size()); |
2114 | 2112 |
2115 if (headers.padding_payload_len() > 0) { | 2113 if (headers.padding_payload_len() > 0) { |
2116 string padding(headers.padding_payload_len(), 0); | 2114 SpdyString padding(headers.padding_payload_len(), 0); |
2117 builder.WriteBytes(padding.data(), padding.length()); | 2115 builder.WriteBytes(padding.data(), padding.length()); |
2118 } | 2116 } |
2119 return builder.take(); | 2117 return builder.take(); |
2120 } | 2118 } |
2121 | 2119 |
2122 SpdySerializedFrame SpdyFramer::SerializeContinuation( | 2120 SpdySerializedFrame SpdyFramer::SerializeContinuation( |
2123 const SpdyContinuationIR& continuation) const { | 2121 const SpdyContinuationIR& continuation) const { |
2124 const string& encoding = continuation.encoding(); | 2122 const SpdyString& encoding = continuation.encoding(); |
2125 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); | 2123 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); |
2126 SpdyFrameBuilder builder(frame_size); | 2124 SpdyFrameBuilder builder(frame_size); |
2127 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; | 2125 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; |
2128 builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, | 2126 builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, |
2129 continuation.stream_id()); | 2127 continuation.stream_id()); |
2130 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); | 2128 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); |
2131 | 2129 |
2132 builder.WriteBytes(encoding.data(), encoding.size()); | 2130 builder.WriteBytes(encoding.data(), encoding.size()); |
2133 return builder.take(); | 2131 return builder.take(); |
2134 } | 2132 } |
2135 | 2133 |
2136 void SpdyFramer::SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir, | 2134 void SpdyFramer::SerializeAltSvcBuilderHelper(const SpdyAltSvcIR& altsvc_ir, |
2137 string* value, | 2135 SpdyString* value, |
2138 size_t* size) const { | 2136 size_t* size) const { |
2139 *size = GetAltSvcMinimumSize(); | 2137 *size = GetAltSvcMinimumSize(); |
2140 *size = *size + altsvc_ir.origin().length(); | 2138 *size = *size + altsvc_ir.origin().length(); |
2141 *value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( | 2139 *value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue( |
2142 altsvc_ir.altsvc_vector()); | 2140 altsvc_ir.altsvc_vector()); |
2143 *size = *size + value->length(); | 2141 *size = *size + value->length(); |
2144 } | 2142 } |
2145 | 2143 |
2146 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { | 2144 SpdySerializedFrame SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir) { |
2147 string value; | 2145 SpdyString value; |
2148 size_t size = 0; | 2146 size_t size = 0; |
2149 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size); | 2147 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size); |
2150 SpdyFrameBuilder builder(size); | 2148 SpdyFrameBuilder builder(size); |
2151 builder.BeginNewFrame(*this, SpdyFrameType::ALTSVC, kNoFlags, | 2149 builder.BeginNewFrame(*this, SpdyFrameType::ALTSVC, kNoFlags, |
2152 altsvc_ir.stream_id()); | 2150 altsvc_ir.stream_id()); |
2153 | 2151 |
2154 builder.WriteUInt16(altsvc_ir.origin().length()); | 2152 builder.WriteUInt16(altsvc_ir.origin().length()); |
2155 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); | 2153 builder.WriteBytes(altsvc_ir.origin().data(), altsvc_ir.origin().length()); |
2156 builder.WriteBytes(value.data(), value.length()); | 2154 builder.WriteBytes(value.data(), value.length()); |
2157 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); | 2155 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2327 | 2325 |
2328 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, | 2326 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, |
2329 data_ir.stream_id()); | 2327 data_ir.stream_id()); |
2330 | 2328 |
2331 if (data_ir.padded()) { | 2329 if (data_ir.padded()) { |
2332 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2330 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
2333 } | 2331 } |
2334 | 2332 |
2335 ok = ok && builder.WriteBytes(data_ir.data(), data_ir.data_len()); | 2333 ok = ok && builder.WriteBytes(data_ir.data(), data_ir.data_len()); |
2336 if (data_ir.padding_payload_len() > 0) { | 2334 if (data_ir.padding_payload_len() > 0) { |
2337 string padding; | 2335 SpdyString padding; |
2338 padding = string(data_ir.padding_payload_len(), 0); | 2336 padding = SpdyString(data_ir.padding_payload_len(), 0); |
2339 ok = ok && builder.WriteBytes(padding.data(), padding.length()); | 2337 ok = ok && builder.WriteBytes(padding.data(), padding.length()); |
2340 } | 2338 } |
2341 DCHECK_EQ(size_with_padding, builder.length()); | 2339 DCHECK_EQ(size_with_padding, builder.length()); |
2342 return ok; | 2340 return ok; |
2343 } | 2341 } |
2344 | 2342 |
2345 bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 2343 bool SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( |
2346 const SpdyDataIR& data_ir, | 2344 const SpdyDataIR& data_ir, |
2347 ZeroCopyOutputBuffer* output) const { | 2345 ZeroCopyOutputBuffer* output) const { |
2348 uint8_t flags = DATA_FLAG_NONE; | 2346 uint8_t flags = DATA_FLAG_NONE; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2451 DCHECK_EQ(expected_length, builder.length()); | 2449 DCHECK_EQ(expected_length, builder.length()); |
2452 return ok; | 2450 return ok; |
2453 } | 2451 } |
2454 | 2452 |
2455 bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers, | 2453 bool SpdyFramer::SerializeHeaders(const SpdyHeadersIR& headers, |
2456 ZeroCopyOutputBuffer* output) { | 2454 ZeroCopyOutputBuffer* output) { |
2457 uint8_t flags = 0; | 2455 uint8_t flags = 0; |
2458 // The size of this frame, including padding (if there is any) and | 2456 // The size of this frame, including padding (if there is any) and |
2459 // variable-length header block. | 2457 // variable-length header block. |
2460 size_t size = 0; | 2458 size_t size = 0; |
2461 string hpack_encoding; | 2459 SpdyString hpack_encoding; |
2462 int weight = 0; | 2460 int weight = 0; |
2463 size_t length_field = 0; | 2461 size_t length_field = 0; |
2464 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, | 2462 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, |
2465 &weight, &length_field); | 2463 &weight, &length_field); |
2466 | 2464 |
2467 bool ok = true; | 2465 bool ok = true; |
2468 SpdyFrameBuilder builder(size, output); | 2466 SpdyFrameBuilder builder(size, output); |
2469 if (!skip_rewritelength_) { | 2467 if (!skip_rewritelength_) { |
2470 ok = builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | 2468 ok = builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, |
2471 headers.stream_id()); | 2469 headers.stream_id()); |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2511 window_update.stream_id()); | 2509 window_update.stream_id()); |
2512 ok = ok && builder.WriteUInt32(window_update.delta()); | 2510 ok = ok && builder.WriteUInt32(window_update.delta()); |
2513 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); | 2511 DCHECK_EQ(GetWindowUpdateSize(), builder.length()); |
2514 return ok; | 2512 return ok; |
2515 } | 2513 } |
2516 | 2514 |
2517 bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise, | 2515 bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise, |
2518 ZeroCopyOutputBuffer* output) { | 2516 ZeroCopyOutputBuffer* output) { |
2519 uint8_t flags = 0; | 2517 uint8_t flags = 0; |
2520 size_t size = 0; | 2518 size_t size = 0; |
2521 string hpack_encoding; | 2519 SpdyString hpack_encoding; |
2522 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, | 2520 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, |
2523 &size); | 2521 &size); |
2524 | 2522 |
2525 bool ok = true; | 2523 bool ok = true; |
2526 SpdyFrameBuilder builder(size, output); | 2524 SpdyFrameBuilder builder(size, output); |
2527 if (!skip_rewritelength_) { | 2525 if (!skip_rewritelength_) { |
2528 ok = builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | 2526 ok = builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, |
2529 push_promise.stream_id()); | 2527 push_promise.stream_id()); |
2530 } else { | 2528 } else { |
2531 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); | 2529 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); |
(...skipping 27 matching lines...) Expand all Loading... |
2559 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), | 2557 debug_visitor_->OnSendCompressedFrame(push_promise.stream_id(), |
2560 SpdyFrameType::PUSH_PROMISE, | 2558 SpdyFrameType::PUSH_PROMISE, |
2561 payload_len, builder.length()); | 2559 payload_len, builder.length()); |
2562 } | 2560 } |
2563 | 2561 |
2564 return ok; | 2562 return ok; |
2565 } | 2563 } |
2566 | 2564 |
2567 bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation, | 2565 bool SpdyFramer::SerializeContinuation(const SpdyContinuationIR& continuation, |
2568 ZeroCopyOutputBuffer* output) const { | 2566 ZeroCopyOutputBuffer* output) const { |
2569 const string& encoding = continuation.encoding(); | 2567 const SpdyString& encoding = continuation.encoding(); |
2570 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); | 2568 size_t frame_size = GetContinuationMinimumSize() + encoding.size(); |
2571 SpdyFrameBuilder builder(frame_size, output); | 2569 SpdyFrameBuilder builder(frame_size, output); |
2572 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; | 2570 uint8_t flags = continuation.end_headers() ? HEADERS_FLAG_END_HEADERS : 0; |
2573 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, | 2571 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, |
2574 continuation.stream_id()); | 2572 continuation.stream_id()); |
2575 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); | 2573 DCHECK_EQ(GetFrameHeaderSize(), builder.length()); |
2576 | 2574 |
2577 ok = ok && builder.WriteBytes(encoding.data(), encoding.size()); | 2575 ok = ok && builder.WriteBytes(encoding.data(), encoding.size()); |
2578 return ok; | 2576 return ok; |
2579 } | 2577 } |
2580 | 2578 |
2581 bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir, | 2579 bool SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc_ir, |
2582 ZeroCopyOutputBuffer* output) { | 2580 ZeroCopyOutputBuffer* output) { |
2583 string value; | 2581 SpdyString value; |
2584 size_t size = 0; | 2582 size_t size = 0; |
2585 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size); | 2583 SerializeAltSvcBuilderHelper(altsvc_ir, &value, &size); |
2586 SpdyFrameBuilder builder(size, output); | 2584 SpdyFrameBuilder builder(size, output); |
2587 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::ALTSVC, kNoFlags, | 2585 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::ALTSVC, kNoFlags, |
2588 altsvc_ir.stream_id()) && | 2586 altsvc_ir.stream_id()) && |
2589 builder.WriteUInt16(altsvc_ir.origin().length()) && | 2587 builder.WriteUInt16(altsvc_ir.origin().length()) && |
2590 builder.WriteBytes(altsvc_ir.origin().data(), | 2588 builder.WriteBytes(altsvc_ir.origin().data(), |
2591 altsvc_ir.origin().length()) && | 2589 altsvc_ir.origin().length()) && |
2592 builder.WriteBytes(value.data(), value.length()); | 2590 builder.WriteBytes(value.data(), value.length()); |
2593 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); | 2591 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); |
(...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2707 if (header_ir.padded()) { | 2705 if (header_ir.padded()) { |
2708 flags |= HEADERS_FLAG_PADDED; | 2706 flags |= HEADERS_FLAG_PADDED; |
2709 } | 2707 } |
2710 if (header_ir.has_priority()) { | 2708 if (header_ir.has_priority()) { |
2711 flags |= HEADERS_FLAG_PRIORITY; | 2709 flags |= HEADERS_FLAG_PRIORITY; |
2712 } | 2710 } |
2713 return flags; | 2711 return flags; |
2714 } | 2712 } |
2715 | 2713 |
2716 bool SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, | 2714 bool SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, |
2717 const string& hpack_encoding, | 2715 const SpdyString& hpack_encoding, |
2718 SpdyStreamId stream_id, | 2716 SpdyStreamId stream_id, |
2719 SpdyFrameType type, | 2717 SpdyFrameType type, |
2720 int padding_payload_len) { | 2718 int padding_payload_len) { |
2721 uint8_t end_flag = 0; | 2719 uint8_t end_flag = 0; |
2722 uint8_t flags = 0; | 2720 uint8_t flags = 0; |
2723 if (type == SpdyFrameType::HEADERS) { | 2721 if (type == SpdyFrameType::HEADERS) { |
2724 end_flag = HEADERS_FLAG_END_HEADERS; | 2722 end_flag = HEADERS_FLAG_END_HEADERS; |
2725 } else if (type == SpdyFrameType::PUSH_PROMISE) { | 2723 } else if (type == SpdyFrameType::PUSH_PROMISE) { |
2726 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2724 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2727 } else { | 2725 } else { |
2728 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " | 2726 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " |
2729 << FrameTypeToString(type); | 2727 << FrameTypeToString(type); |
2730 } | 2728 } |
2731 | 2729 |
2732 // Write all the padding payload and as much of the data payload as | 2730 // Write all the padding payload and as much of the data payload as |
2733 // possible into the initial frame. | 2731 // possible into the initial frame. |
2734 size_t bytes_remaining = 0; | 2732 size_t bytes_remaining = 0; |
2735 bytes_remaining = | 2733 bytes_remaining = |
2736 hpack_encoding.size() - | 2734 hpack_encoding.size() - |
2737 std::min(hpack_encoding.size(), | 2735 std::min(hpack_encoding.size(), |
2738 kMaxControlFrameSize - builder->length() - padding_payload_len); | 2736 kMaxControlFrameSize - builder->length() - padding_payload_len); |
2739 bool ret = builder->WriteBytes(&hpack_encoding[0], | 2737 bool ret = builder->WriteBytes(&hpack_encoding[0], |
2740 hpack_encoding.size() - bytes_remaining); | 2738 hpack_encoding.size() - bytes_remaining); |
2741 if (padding_payload_len > 0) { | 2739 if (padding_payload_len > 0) { |
2742 string padding = string(padding_payload_len, 0); | 2740 SpdyString padding = SpdyString(padding_payload_len, 0); |
2743 ret &= builder->WriteBytes(padding.data(), padding.length()); | 2741 ret &= builder->WriteBytes(padding.data(), padding.length()); |
2744 } | 2742 } |
2745 if (bytes_remaining > 0 && !skip_rewritelength_) { | 2743 if (bytes_remaining > 0 && !skip_rewritelength_) { |
2746 ret &= builder->OverwriteLength( | 2744 ret &= builder->OverwriteLength( |
2747 *this, kMaxControlFrameSize - GetFrameHeaderSize()); | 2745 *this, kMaxControlFrameSize - GetFrameHeaderSize()); |
2748 } | 2746 } |
2749 | 2747 |
2750 // Tack on CONTINUATION frames for the overflow. | 2748 // Tack on CONTINUATION frames for the overflow. |
2751 while (bytes_remaining > 0 && ret) { | 2749 while (bytes_remaining > 0 && ret) { |
2752 size_t bytes_to_write = std::min( | 2750 size_t bytes_to_write = std::min( |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2838 builder->WriteUInt32(header_block.size()); | 2836 builder->WriteUInt32(header_block.size()); |
2839 | 2837 |
2840 // Serialize each header. | 2838 // Serialize each header. |
2841 for (const auto& header : header_block) { | 2839 for (const auto& header : header_block) { |
2842 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 2840 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
2843 builder->WriteStringPiece32(header.second); | 2841 builder->WriteStringPiece32(header.second); |
2844 } | 2842 } |
2845 } | 2843 } |
2846 | 2844 |
2847 } // namespace net | 2845 } // namespace net |
OLD | NEW |