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/core/spdy_framer.h" | 5 #include "net/spdy/core/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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 probable_http_response_(false), | 136 probable_http_response_(false), |
137 end_stream_when_done_(false) { | 137 end_stream_when_done_(false) { |
138 static_assert( | 138 static_assert( |
139 kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit + kFrameHeaderSize, | 139 kMaxControlFrameSize <= kSpdyInitialFrameSizeLimit + kFrameHeaderSize, |
140 "Our send limit should be at most our receive limit"); | 140 "Our send limit should be at most our receive limit"); |
141 Reset(); | 141 Reset(); |
142 | 142 |
143 if (adapter_factory != nullptr) { | 143 if (adapter_factory != nullptr) { |
144 decoder_adapter_ = adapter_factory(this); | 144 decoder_adapter_ = adapter_factory(this); |
145 } | 145 } |
146 skip_rewritelength_ = FLAGS_chromium_http2_flag_remove_rewritelength; | |
147 } | 146 } |
148 | 147 |
149 SpdyFramer::SpdyFramer(CompressionOption option) | 148 SpdyFramer::SpdyFramer(CompressionOption option) |
150 : SpdyFramer(&DecoderAdapterFactory, option) {} | 149 : SpdyFramer(&DecoderAdapterFactory, option) {} |
151 | 150 |
152 SpdyFramer::~SpdyFramer() {} | 151 SpdyFramer::~SpdyFramer() {} |
153 | 152 |
154 void SpdyFramer::Reset() { | 153 void SpdyFramer::Reset() { |
155 if (decoder_adapter_ != nullptr) { | 154 if (decoder_adapter_ != nullptr) { |
156 decoder_adapter_->Reset(); | 155 decoder_adapter_->Reset(); |
(...skipping 1713 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1870 | 1869 |
1871 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( | 1870 SpdySerializedFrame SpdyFramer::SerializeDataFrameHeaderWithPaddingLengthField( |
1872 const SpdyDataIR& data_ir) const { | 1871 const SpdyDataIR& data_ir) const { |
1873 uint8_t flags = DATA_FLAG_NONE; | 1872 uint8_t flags = DATA_FLAG_NONE; |
1874 size_t frame_size = 0; | 1873 size_t frame_size = 0; |
1875 size_t num_padding_fields = 0; | 1874 size_t num_padding_fields = 0; |
1876 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( | 1875 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( |
1877 data_ir, &flags, &frame_size, &num_padding_fields); | 1876 data_ir, &flags, &frame_size, &num_padding_fields); |
1878 | 1877 |
1879 SpdyFrameBuilder builder(frame_size); | 1878 SpdyFrameBuilder builder(frame_size); |
1880 if (!skip_rewritelength_) { | 1879 builder.BeginNewFrame( |
1881 builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, | 1880 *this, SpdyFrameType::DATA, flags, data_ir.stream_id(), |
1882 data_ir.stream_id()); | 1881 num_padding_fields + data_ir.data_len() + data_ir.padding_payload_len()); |
1883 if (data_ir.padded()) { | 1882 if (data_ir.padded()) { |
1884 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 1883 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
1885 } | |
1886 builder.OverwriteLength(*this, num_padding_fields + data_ir.data_len() + | |
1887 data_ir.padding_payload_len()); | |
1888 } else { | |
1889 builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, | |
1890 data_ir.stream_id(), | |
1891 num_padding_fields + data_ir.data_len() + | |
1892 data_ir.padding_payload_len()); | |
1893 if (data_ir.padded()) { | |
1894 builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | |
1895 } | |
1896 } | 1884 } |
1897 DCHECK_EQ(frame_size, builder.length()); | 1885 DCHECK_EQ(frame_size, builder.length()); |
1898 return builder.take(); | 1886 return builder.take(); |
1899 } | 1887 } |
1900 | 1888 |
1901 SpdySerializedFrame SpdyFramer::SerializeRstStream( | 1889 SpdySerializedFrame SpdyFramer::SerializeRstStream( |
1902 const SpdyRstStreamIR& rst_stream) const { | 1890 const SpdyRstStreamIR& rst_stream) const { |
1903 size_t expected_length = GetRstStreamSize(); | 1891 size_t expected_length = GetRstStreamSize(); |
1904 SpdyFrameBuilder builder(expected_length); | 1892 SpdyFrameBuilder builder(expected_length); |
1905 | 1893 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2047 // The size of this frame, including padding (if there is any) and | 2035 // The size of this frame, including padding (if there is any) and |
2048 // variable-length header block. | 2036 // variable-length header block. |
2049 size_t size = 0; | 2037 size_t size = 0; |
2050 SpdyString hpack_encoding; | 2038 SpdyString hpack_encoding; |
2051 int weight = 0; | 2039 int weight = 0; |
2052 size_t length_field = 0; | 2040 size_t length_field = 0; |
2053 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, | 2041 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, |
2054 &weight, &length_field); | 2042 &weight, &length_field); |
2055 | 2043 |
2056 SpdyFrameBuilder builder(size); | 2044 SpdyFrameBuilder builder(size); |
| 2045 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, |
| 2046 headers.stream_id(), length_field); |
2057 | 2047 |
2058 if (!skip_rewritelength_) { | |
2059 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | |
2060 headers.stream_id()); | |
2061 } else { | |
2062 builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | |
2063 headers.stream_id(), length_field); | |
2064 } | |
2065 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2048 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2066 | 2049 |
2067 int padding_payload_len = 0; | 2050 int padding_payload_len = 0; |
2068 if (headers.padded()) { | 2051 if (headers.padded()) { |
2069 builder.WriteUInt8(headers.padding_payload_len()); | 2052 builder.WriteUInt8(headers.padding_payload_len()); |
2070 padding_payload_len = headers.padding_payload_len(); | 2053 padding_payload_len = headers.padding_payload_len(); |
2071 } | 2054 } |
2072 if (headers.has_priority()) { | 2055 if (headers.has_priority()) { |
2073 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), | 2056 builder.WriteUInt32(PackStreamDependencyValues(headers.exclusive(), |
2074 headers.parent_stream_id())); | 2057 headers.parent_stream_id())); |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2130 | 2113 |
2131 SpdySerializedFrame SpdyFramer::SerializePushPromise( | 2114 SpdySerializedFrame SpdyFramer::SerializePushPromise( |
2132 const SpdyPushPromiseIR& push_promise) { | 2115 const SpdyPushPromiseIR& push_promise) { |
2133 uint8_t flags = 0; | 2116 uint8_t flags = 0; |
2134 size_t size = 0; | 2117 size_t size = 0; |
2135 SpdyString hpack_encoding; | 2118 SpdyString hpack_encoding; |
2136 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, | 2119 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, |
2137 &size); | 2120 &size); |
2138 | 2121 |
2139 SpdyFrameBuilder builder(size); | 2122 SpdyFrameBuilder builder(size); |
2140 if (!skip_rewritelength_) { | 2123 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); |
2141 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | 2124 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, |
2142 push_promise.stream_id()); | 2125 push_promise.stream_id(), length); |
2143 } else { | |
2144 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); | |
2145 builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | |
2146 push_promise.stream_id(), length); | |
2147 } | |
2148 int padding_payload_len = 0; | 2126 int padding_payload_len = 0; |
2149 if (push_promise.padded()) { | 2127 if (push_promise.padded()) { |
2150 builder.WriteUInt8(push_promise.padding_payload_len()); | 2128 builder.WriteUInt8(push_promise.padding_payload_len()); |
2151 builder.WriteUInt32(push_promise.promised_stream_id()); | 2129 builder.WriteUInt32(push_promise.promised_stream_id()); |
2152 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, | 2130 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, |
2153 builder.length()); | 2131 builder.length()); |
2154 | 2132 |
2155 padding_payload_len = push_promise.padding_payload_len(); | 2133 padding_payload_len = push_promise.padding_payload_len(); |
2156 } else { | 2134 } else { |
2157 builder.WriteUInt32(push_promise.promised_stream_id()); | 2135 builder.WriteUInt32(push_promise.promised_stream_id()); |
(...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2441 const SpdyDataIR& data_ir, | 2419 const SpdyDataIR& data_ir, |
2442 ZeroCopyOutputBuffer* output) const { | 2420 ZeroCopyOutputBuffer* output) const { |
2443 uint8_t flags = DATA_FLAG_NONE; | 2421 uint8_t flags = DATA_FLAG_NONE; |
2444 size_t frame_size = 0; | 2422 size_t frame_size = 0; |
2445 size_t num_padding_fields = 0; | 2423 size_t num_padding_fields = 0; |
2446 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( | 2424 SerializeDataFrameHeaderWithPaddingLengthFieldBuilderHelper( |
2447 data_ir, &flags, &frame_size, &num_padding_fields); | 2425 data_ir, &flags, &frame_size, &num_padding_fields); |
2448 | 2426 |
2449 SpdyFrameBuilder builder(frame_size, output); | 2427 SpdyFrameBuilder builder(frame_size, output); |
2450 bool ok = true; | 2428 bool ok = true; |
2451 if (!skip_rewritelength_) { | 2429 ok = ok && builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, |
2452 ok = builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, | 2430 data_ir.stream_id(), |
2453 data_ir.stream_id()); | 2431 num_padding_fields + data_ir.data_len() + |
2454 if (data_ir.padded()) { | 2432 data_ir.padding_payload_len()); |
2455 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | 2433 if (data_ir.padded()) { |
2456 } | 2434 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); |
2457 ok = ok && builder.OverwriteLength(*this, | |
2458 num_padding_fields + data_ir.data_len() + | |
2459 data_ir.padding_payload_len()); | |
2460 } else { | |
2461 ok = ok && builder.BeginNewFrame(*this, SpdyFrameType::DATA, flags, | |
2462 data_ir.stream_id(), | |
2463 num_padding_fields + data_ir.data_len() + | |
2464 data_ir.padding_payload_len()); | |
2465 if (data_ir.padded()) { | |
2466 ok = ok && builder.WriteUInt8(data_ir.padding_payload_len() & 0xff); | |
2467 } | |
2468 } | 2435 } |
2469 DCHECK_EQ(frame_size, builder.length()); | 2436 DCHECK_EQ(frame_size, builder.length()); |
2470 return ok; | 2437 return ok; |
2471 } | 2438 } |
2472 | 2439 |
2473 bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream, | 2440 bool SpdyFramer::SerializeRstStream(const SpdyRstStreamIR& rst_stream, |
2474 ZeroCopyOutputBuffer* output) const { | 2441 ZeroCopyOutputBuffer* output) const { |
2475 size_t expected_length = GetRstStreamSize(); | 2442 size_t expected_length = GetRstStreamSize(); |
2476 SpdyFrameBuilder builder(expected_length, output); | 2443 SpdyFrameBuilder builder(expected_length, output); |
2477 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::RST_STREAM, 0, | 2444 bool ok = builder.BeginNewFrame(*this, SpdyFrameType::RST_STREAM, 0, |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2554 // variable-length header block. | 2521 // variable-length header block. |
2555 size_t size = 0; | 2522 size_t size = 0; |
2556 SpdyString hpack_encoding; | 2523 SpdyString hpack_encoding; |
2557 int weight = 0; | 2524 int weight = 0; |
2558 size_t length_field = 0; | 2525 size_t length_field = 0; |
2559 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, | 2526 SerializeHeadersBuilderHelper(headers, &flags, &size, &hpack_encoding, |
2560 &weight, &length_field); | 2527 &weight, &length_field); |
2561 | 2528 |
2562 bool ok = true; | 2529 bool ok = true; |
2563 SpdyFrameBuilder builder(size, output); | 2530 SpdyFrameBuilder builder(size, output); |
2564 if (!skip_rewritelength_) { | 2531 ok = ok && builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, |
2565 ok = builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | 2532 headers.stream_id(), length_field); |
2566 headers.stream_id()); | |
2567 } else { | |
2568 ok = ok && builder.BeginNewFrame(*this, SpdyFrameType::HEADERS, flags, | |
2569 headers.stream_id(), length_field); | |
2570 } | |
2571 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2533 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2572 | 2534 |
2573 int padding_payload_len = 0; | 2535 int padding_payload_len = 0; |
2574 if (headers.padded()) { | 2536 if (headers.padded()) { |
2575 ok = ok && builder.WriteUInt8(headers.padding_payload_len()); | 2537 ok = ok && builder.WriteUInt8(headers.padding_payload_len()); |
2576 padding_payload_len = headers.padding_payload_len(); | 2538 padding_payload_len = headers.padding_payload_len(); |
2577 } | 2539 } |
2578 if (headers.has_priority()) { | 2540 if (headers.has_priority()) { |
2579 ok = ok && | 2541 ok = ok && |
2580 builder.WriteUInt32(PackStreamDependencyValues( | 2542 builder.WriteUInt32(PackStreamDependencyValues( |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2612 bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise, | 2574 bool SpdyFramer::SerializePushPromise(const SpdyPushPromiseIR& push_promise, |
2613 ZeroCopyOutputBuffer* output) { | 2575 ZeroCopyOutputBuffer* output) { |
2614 uint8_t flags = 0; | 2576 uint8_t flags = 0; |
2615 size_t size = 0; | 2577 size_t size = 0; |
2616 SpdyString hpack_encoding; | 2578 SpdyString hpack_encoding; |
2617 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, | 2579 SerializePushPromiseBuilderHelper(push_promise, &flags, &hpack_encoding, |
2618 &size); | 2580 &size); |
2619 | 2581 |
2620 bool ok = true; | 2582 bool ok = true; |
2621 SpdyFrameBuilder builder(size, output); | 2583 SpdyFrameBuilder builder(size, output); |
2622 if (!skip_rewritelength_) { | 2584 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); |
2623 ok = builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | 2585 ok = builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, |
2624 push_promise.stream_id()); | 2586 push_promise.stream_id(), length); |
2625 } else { | |
2626 size_t length = std::min(size, kMaxControlFrameSize) - GetFrameHeaderSize(); | |
2627 ok = builder.BeginNewFrame(*this, SpdyFrameType::PUSH_PROMISE, flags, | |
2628 push_promise.stream_id(), length); | |
2629 } | |
2630 | 2587 |
2631 int padding_payload_len = 0; | 2588 int padding_payload_len = 0; |
2632 if (push_promise.padded()) { | 2589 if (push_promise.padded()) { |
2633 ok = ok && builder.WriteUInt8(push_promise.padding_payload_len()) && | 2590 ok = ok && builder.WriteUInt8(push_promise.padding_payload_len()) && |
2634 builder.WriteUInt32(push_promise.promised_stream_id()); | 2591 builder.WriteUInt32(push_promise.promised_stream_id()); |
2635 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, | 2592 DCHECK_EQ(GetPushPromiseMinimumSize() + kPadLengthFieldSize, |
2636 builder.length()); | 2593 builder.length()); |
2637 | 2594 |
2638 padding_payload_len = push_promise.padding_payload_len(); | 2595 padding_payload_len = push_promise.padding_payload_len(); |
2639 } else { | 2596 } else { |
(...skipping 245 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2885 bytes_remaining = | 2842 bytes_remaining = |
2886 hpack_encoding.size() - | 2843 hpack_encoding.size() - |
2887 std::min(hpack_encoding.size(), | 2844 std::min(hpack_encoding.size(), |
2888 kMaxControlFrameSize - builder->length() - padding_payload_len); | 2845 kMaxControlFrameSize - builder->length() - padding_payload_len); |
2889 bool ret = builder->WriteBytes(&hpack_encoding[0], | 2846 bool ret = builder->WriteBytes(&hpack_encoding[0], |
2890 hpack_encoding.size() - bytes_remaining); | 2847 hpack_encoding.size() - bytes_remaining); |
2891 if (padding_payload_len > 0) { | 2848 if (padding_payload_len > 0) { |
2892 SpdyString padding = SpdyString(padding_payload_len, 0); | 2849 SpdyString padding = SpdyString(padding_payload_len, 0); |
2893 ret &= builder->WriteBytes(padding.data(), padding.length()); | 2850 ret &= builder->WriteBytes(padding.data(), padding.length()); |
2894 } | 2851 } |
2895 if (bytes_remaining > 0 && !skip_rewritelength_) { | |
2896 ret &= builder->OverwriteLength( | |
2897 *this, kMaxControlFrameSize - GetFrameHeaderSize()); | |
2898 } | |
2899 | 2852 |
2900 // Tack on CONTINUATION frames for the overflow. | 2853 // Tack on CONTINUATION frames for the overflow. |
2901 while (bytes_remaining > 0 && ret) { | 2854 while (bytes_remaining > 0 && ret) { |
2902 size_t bytes_to_write = std::min( | 2855 size_t bytes_to_write = std::min( |
2903 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); | 2856 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize()); |
2904 // Write CONTINUATION frame prefix. | 2857 // Write CONTINUATION frame prefix. |
2905 if (bytes_remaining == bytes_to_write) { | 2858 if (bytes_remaining == bytes_to_write) { |
2906 flags |= end_flag; | 2859 flags |= end_flag; |
2907 } | 2860 } |
2908 if (!skip_rewritelength_) { | 2861 ret &= builder->BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, |
2909 ret &= builder->BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, | 2862 stream_id, bytes_to_write); |
2910 stream_id); | |
2911 } else { | |
2912 ret &= builder->BeginNewFrame(*this, SpdyFrameType::CONTINUATION, flags, | |
2913 stream_id, bytes_to_write); | |
2914 } | |
2915 // Write payload fragment. | 2863 // Write payload fragment. |
2916 ret &= builder->WriteBytes( | 2864 ret &= builder->WriteBytes( |
2917 &hpack_encoding[hpack_encoding.size() - bytes_remaining], | 2865 &hpack_encoding[hpack_encoding.size() - bytes_remaining], |
2918 bytes_to_write); | 2866 bytes_to_write); |
2919 bytes_remaining -= bytes_to_write; | 2867 bytes_remaining -= bytes_to_write; |
2920 } | 2868 } |
2921 return ret; | 2869 return ret; |
2922 } | 2870 } |
2923 | 2871 |
2924 HpackEncoder* SpdyFramer::GetHpackEncoder() { | 2872 HpackEncoder* SpdyFramer::GetHpackEncoder() { |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2988 builder->WriteUInt32(header_block.size()); | 2936 builder->WriteUInt32(header_block.size()); |
2989 | 2937 |
2990 // Serialize each header. | 2938 // Serialize each header. |
2991 for (const auto& header : header_block) { | 2939 for (const auto& header : header_block) { |
2992 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); | 2940 builder->WriteStringPiece32(base::ToLowerASCII(header.first)); |
2993 builder->WriteStringPiece32(header.second); | 2941 builder->WriteStringPiece32(header.second); |
2994 } | 2942 } |
2995 } | 2943 } |
2996 | 2944 |
2997 } // namespace net | 2945 } // namespace net |
OLD | NEW |