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> |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
152 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it | 152 // TODO(bnc): The way kMaxControlFrameSize is currently interpreted, it |
153 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. | 153 // includes the frame header, whereas kSpdyInitialFrameSizeLimit does not. |
154 // Therefore this assertion is unnecessarily strict. | 154 // Therefore this assertion is unnecessarily strict. |
155 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, | 155 static_assert(kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit, |
156 "Our send limit should be at most our receive limit"); | 156 "Our send limit should be at most our receive limit"); |
157 Reset(); | 157 Reset(); |
158 | 158 |
159 if (adapter_factory != nullptr) { | 159 if (adapter_factory != nullptr) { |
160 decoder_adapter_ = adapter_factory(this); | 160 decoder_adapter_ = adapter_factory(this); |
161 } | 161 } |
| 162 skip_rewritelength_ = FLAGS_chromium_http2_flag_remove_rewritelength; |
162 } | 163 } |
163 | 164 |
164 SpdyFramer::SpdyFramer(CompressionOption option) | 165 SpdyFramer::SpdyFramer(CompressionOption option) |
165 : SpdyFramer(&DecoderAdapterFactory, option) {} | 166 : SpdyFramer(&DecoderAdapterFactory, option) {} |
166 | 167 |
167 SpdyFramer::~SpdyFramer() { | 168 SpdyFramer::~SpdyFramer() { |
168 } | 169 } |
169 | 170 |
170 void SpdyFramer::Reset() { | 171 void SpdyFramer::Reset() { |
171 if (decoder_adapter_ != nullptr) { | 172 if (decoder_adapter_ != nullptr) { |
(...skipping 1681 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1853 | 1854 |
1854 size_t frame_size = GetDataFrameMinimumSize(); | 1855 size_t frame_size = GetDataFrameMinimumSize(); |
1855 size_t num_padding_fields = 0; | 1856 size_t num_padding_fields = 0; |
1856 if (data_ir.padded()) { | 1857 if (data_ir.padded()) { |
1857 flags |= DATA_FLAG_PADDED; | 1858 flags |= DATA_FLAG_PADDED; |
1858 ++num_padding_fields; | 1859 ++num_padding_fields; |
1859 frame_size += num_padding_fields; | 1860 frame_size += num_padding_fields; |
1860 } | 1861 } |
1861 | 1862 |
1862 SpdyFrameBuilder builder(frame_size); | 1863 SpdyFrameBuilder builder(frame_size); |
1863 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); | 1864 if (!skip_rewritelength_) { |
1864 if (data_ir.padded()) { | 1865 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id()); |
1865 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 1866 if (data_ir.padded()) { |
| 1867 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 1868 } |
| 1869 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + |
| 1870 data_ir.padding_payload_len()); |
| 1871 } else { |
| 1872 builder.BeginNewFrame(*this, DATA, flags, data_ir.stream_id(), |
| 1873 num_padding_fields + data_ir.data_len() + |
| 1874 data_ir.padding_payload_len()); |
| 1875 if (data_ir.padded()) { |
| 1876 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
| 1877 } |
1866 } | 1878 } |
1867 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + | |
1868 data_ir.padding_payload_len()); | |
1869 DCHECK_EQ(frame_size, builder.length()); | 1879 DCHECK_EQ(frame_size, builder.length()); |
1870 return builder.take(); | 1880 return builder.take(); |
1871 } | 1881 } |
1872 | 1882 |
1873 SpdySerializedFrame SpdyFramer::SerializeRstStream( | 1883 SpdySerializedFrame SpdyFramer::SerializeRstStream( |
1874 const SpdyRstStreamIR& rst_stream) const { | 1884 const SpdyRstStreamIR& rst_stream) const { |
1875 size_t expected_length = GetRstStreamSize(); | 1885 size_t expected_length = GetRstStreamSize(); |
1876 SpdyFrameBuilder builder(expected_length); | 1886 SpdyFrameBuilder builder(expected_length); |
1877 | 1887 |
1878 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); | 1888 builder.BeginNewFrame(*this, RST_STREAM, 0, rst_stream.stream_id()); |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1986 string hpack_encoding; | 1996 string hpack_encoding; |
1987 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding); | 1997 GetHpackEncoder()->EncodeHeaderSet(headers.header_block(), &hpack_encoding); |
1988 size += hpack_encoding.size(); | 1998 size += hpack_encoding.size(); |
1989 if (size > kMaxControlFrameSize) { | 1999 if (size > kMaxControlFrameSize) { |
1990 size += GetNumberRequiredContinuationFrames(size) * | 2000 size += GetNumberRequiredContinuationFrames(size) * |
1991 GetContinuationMinimumSize(); | 2001 GetContinuationMinimumSize(); |
1992 flags &= ~HEADERS_FLAG_END_HEADERS; | 2002 flags &= ~HEADERS_FLAG_END_HEADERS; |
1993 } | 2003 } |
1994 | 2004 |
1995 SpdyFrameBuilder builder(size); | 2005 SpdyFrameBuilder builder(size); |
1996 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); | 2006 |
| 2007 if (!skip_rewritelength_) { |
| 2008 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id()); |
| 2009 } else { |
| 2010 // Compute frame length field. |
| 2011 size_t length_field = 0; |
| 2012 if (headers.padded()) { |
| 2013 length_field += 1; // Padding length field. |
| 2014 } |
| 2015 if (headers.has_priority()) { |
| 2016 length_field += 4; // Dependency field. |
| 2017 length_field += 1; // Weight field. |
| 2018 } |
| 2019 length_field += headers.padding_payload_len(); |
| 2020 length_field += hpack_encoding.size(); |
| 2021 // If the HEADERS frame with payload would exceed the max frame size, then |
| 2022 // WritePayloadWithContinuation() will serialize CONTINUATION frames as |
| 2023 // necessary. |
| 2024 length_field = |
| 2025 std::min(length_field, kMaxControlFrameSize - GetFrameHeaderSize()); |
| 2026 builder.BeginNewFrame(*this, HEADERS, flags, headers.stream_id(), |
| 2027 length_field); |
| 2028 } |
1997 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2029 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
1998 | 2030 |
1999 int padding_payload_len = 0; | 2031 int padding_payload_len = 0; |
2000 if (headers.padded()) { | 2032 if (headers.padded()) { |
2001 builder.WriteUInt8(headers.padding_payload_len()); | 2033 builder.WriteUInt8(headers.padding_payload_len()); |
2002 padding_payload_len = headers.padding_payload_len(); | 2034 padding_payload_len = headers.padding_payload_len(); |
2003 } | 2035 } |
2004 if (headers.has_priority()) { | 2036 if (headers.has_priority()) { |
2005 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), | 2037 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
2006 headers.parent_stream_id())); | 2038 headers.parent_stream_id())); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2059 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), | 2091 GetHpackEncoder()->EncodeHeaderSet(push_promise.header_block(), |
2060 &hpack_encoding); | 2092 &hpack_encoding); |
2061 size += hpack_encoding.size(); | 2093 size += hpack_encoding.size(); |
2062 if (size > kMaxControlFrameSize) { | 2094 if (size > kMaxControlFrameSize) { |
2063 size += GetNumberRequiredContinuationFrames(size) * | 2095 size += GetNumberRequiredContinuationFrames(size) * |
2064 GetContinuationMinimumSize(); | 2096 GetContinuationMinimumSize(); |
2065 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; | 2097 flags &= ~PUSH_PROMISE_FLAG_END_PUSH_PROMISE; |
2066 } | 2098 } |
2067 | 2099 |
2068 SpdyFrameBuilder builder(size); | 2100 SpdyFrameBuilder builder(size); |
2069 builder.BeginNewFrame(*this, | 2101 if (!skip_rewritelength_) { |
2070 PUSH_PROMISE, | 2102 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id()); |
2071 flags, | 2103 } else { |
2072 push_promise.stream_id()); | 2104 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); |
| 2105 builder.BeginNewFrame(*this, PUSH_PROMISE, flags, push_promise.stream_id(), |
| 2106 length); |
| 2107 } |
2073 int padding_payload_len = 0; | 2108 int padding_payload_len = 0; |
2074 if (push_promise.padded()) { | 2109 if (push_promise.padded()) { |
2075 builder.WriteUInt8(push_promise.padding_payload_len()); | 2110 builder.WriteUInt8(push_promise.padding_payload_len()); |
2076 builder.WriteUInt32(push_promise.promised_stream_id()); | 2111 builder.WriteUInt32(push_promise.promised_stream_id()); |
2077 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, | 2112 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, |
2078 builder.length()); | 2113 builder.length()); |
2079 | 2114 |
2080 padding_payload_len = push_promise.padding_payload_len(); | 2115 padding_payload_len = push_promise.padding_payload_len(); |
2081 } else { | 2116 } else { |
2082 builder.WriteUInt32(push_promise.promised_stream_id()); | 2117 builder.WriteUInt32(push_promise.promised_stream_id()); |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2392 bytes_remaining = | 2427 bytes_remaining = |
2393 hpack_encoding.size() - | 2428 hpack_encoding.size() - |
2394 std::min(hpack_encoding.size(), | 2429 std::min(hpack_encoding.size(), |
2395 kMaxControlFrameSize - builder->length() - padding_payload_len); | 2430 kMaxControlFrameSize - builder->length() - padding_payload_len); |
2396 builder->WriteBytes(&hpack_encoding[0], | 2431 builder->WriteBytes(&hpack_encoding[0], |
2397 hpack_encoding.size() - bytes_remaining); | 2432 hpack_encoding.size() - bytes_remaining); |
2398 if (padding_payload_len > 0) { | 2433 if (padding_payload_len > 0) { |
2399 string padding = string(padding_payload_len, 0); | 2434 string padding = string(padding_payload_len, 0); |
2400 builder->WriteBytes(padding.data(), padding.length()); | 2435 builder->WriteBytes(padding.data(), padding.length()); |
2401 } | 2436 } |
2402 if (bytes_remaining > 0) { | 2437 if (bytes_remaining > 0 && !skip_rewritelength_) { |
2403 builder->OverwriteLength(*this, | 2438 builder->OverwriteLength(*this, |
2404 kMaxControlFrameSize - GetFrameHeaderSize()); | 2439 kMaxControlFrameSize - GetFrameHeaderSize()); |
2405 } | 2440 } |
2406 | 2441 |
2407 // Tack on CONTINUATION frames for the overflow. | 2442 // Tack on CONTINUATION frames for the overflow. |
2408 while (bytes_remaining > 0) { | 2443 while (bytes_remaining > 0) { |
2409 size_t bytes_to_write = std::min( | 2444 size_t bytes_to_write = std::min( |
2410 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); | 2445 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); |
2411 // Write CONTINUATION frame prefix. | 2446 // Write CONTINUATION frame prefix. |
2412 if (bytes_remaining == bytes_to_write) { | 2447 if (bytes_remaining == bytes_to_write) { |
2413 flags |= end_flag; | 2448 flags |= end_flag; |
2414 } | 2449 } |
2415 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); | 2450 if (!skip_rewritelength_) { |
| 2451 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id); |
| 2452 } else { |
| 2453 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id, |
| 2454 bytes_to_write); |
| 2455 } |
2416 // Write payload fragment. | 2456 // Write payload fragment. |
2417 builder->WriteBytes( | 2457 builder->WriteBytes( |
2418 &hpack_encoding[hpack_encoding.size() - bytes_remaining], | 2458 &hpack_encoding[hpack_encoding.size() - bytes_remaining], |
2419 bytes_to_write); | 2459 bytes_to_write); |
2420 bytes_remaining -= bytes_to_write; | 2460 bytes_remaining -= bytes_to_write; |
2421 } | 2461 } |
2422 } | 2462 } |
2423 | 2463 |
2424 HpackEncoder* SpdyFramer::GetHpackEncoder() { | 2464 HpackEncoder* SpdyFramer::GetHpackEncoder() { |
2425 if (hpack_encoder_.get() == nullptr) { | 2465 if (hpack_encoder_.get() == nullptr) { |
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2500 builder->WriteUInt32(header_block.size()); | 2540 builder->WriteUInt32(header_block.size()); |
2501 | 2541 |
2502 // Serialize each header. | 2542 // Serialize each header. |
2503 for (const auto& header : header_block) { | 2543 for (const auto& header : header_block) { |
2504 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 2544 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
2505 builder->WriteStringPiece32(header.second); | 2545 builder->WriteStringPiece32(header.second); |
2506 } | 2546 } |
2507 } | 2547 } |
2508 | 2548 |
2509 } // namespace net | 2549 } // namespace net |
OLD | NEW |