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

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

Issue 1130053007: Update HTTP/2 ALTSVC wireformat from draft-04 to draft-06. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Hack around win_chromium_compile_dbg_ng linker errors. Created 5 years, 7 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
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <algorithm>
8 #include <limits>
9 #include <string>
10
7 #include "base/lazy_instance.h" 11 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 12 #include "base/memory/scoped_ptr.h"
9 #include "base/third_party/valgrind/memcheck.h" 13 #include "base/third_party/valgrind/memcheck.h"
14 #include "net/spdy/spdy_alt_svc_wire_format.h"
10 #include "net/spdy/spdy_frame_builder.h" 15 #include "net/spdy/spdy_frame_builder.h"
11 #include "net/spdy/spdy_frame_reader.h" 16 #include "net/spdy/spdy_frame_reader.h"
12 #include "net/spdy/spdy_bitmasks.h" 17 #include "net/spdy/spdy_bitmasks.h"
13 #include "third_party/zlib/zlib.h" 18 #include "third_party/zlib/zlib.h"
14 19
15 using base::StringPiece; 20 using base::StringPiece;
16 using std::string; 21 using std::string;
17 using std::vector; 22 using std::vector;
18 23
19 namespace net { 24 namespace net {
(...skipping 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
336 return GetControlFrameHeaderSize() + 4; 341 return GetControlFrameHeaderSize() + 4;
337 } 342 }
338 343
339 size_t SpdyFramer::GetContinuationMinimumSize() const { 344 size_t SpdyFramer::GetContinuationMinimumSize() const {
340 // Size, in bytes, of a CONTINUATION frame not including the variable-length 345 // Size, in bytes, of a CONTINUATION frame not including the variable-length
341 // headers fragments. 346 // headers fragments.
342 return GetControlFrameHeaderSize(); 347 return GetControlFrameHeaderSize();
343 } 348 }
344 349
345 size_t SpdyFramer::GetAltSvcMinimumSize() const { 350 size_t SpdyFramer::GetAltSvcMinimumSize() const {
346 // Size, in bytes, of an ALTSVC frame not including the Protocol-ID, Host, and 351 // Size, in bytes, of an ALTSVC frame not including the Field-Value and
347 // (optional) Origin fields, all of which can vary in length. 352 // (optional) Origin fields, both of which can vary in length. Note that this
348 // Note that this gives a lower bound on the frame size rather than a true 353 // gives a lower bound on the frame size rather than a true minimum; the
349 // minimum; the actual frame should always be larger than this. 354 // actual frame should always be larger than this.
350 // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte) 355 // Calculated as frame prefix + 2 (origin_len).
351 // + 1 (pid_len) + 1 (host_len). 356 return GetControlFrameHeaderSize() + 2;
352 return GetControlFrameHeaderSize() + 9;
353 } 357 }
354 358
355 size_t SpdyFramer::GetPrioritySize() const { 359 size_t SpdyFramer::GetPrioritySize() const {
356 // Size, in bytes, of a PRIORITY frame. 360 // Size, in bytes, of a PRIORITY frame.
357 return GetControlFrameHeaderSize() + 361 return GetControlFrameHeaderSize() +
358 kPriorityDependencyPayloadSize + 362 kPriorityDependencyPayloadSize +
359 kPriorityWeightPayloadSize; 363 kPriorityWeightPayloadSize;
360 } 364 }
361 365
362 size_t SpdyFramer::GetFrameMinimumSize() const { 366 size_t SpdyFramer::GetFrameMinimumSize() const {
(...skipping 1659 matching lines...) Expand 10 before | Expand all | Expand 10 after
2022 } 2026 }
2023 2027
2024 size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) { 2028 size_t SpdyFramer::ProcessAltSvcFramePayload(const char* data, size_t len) {
2025 if (len == 0) { 2029 if (len == 0) {
2026 return 0; 2030 return 0;
2027 } 2031 }
2028 2032
2029 // Clamp to the actual remaining payload. 2033 // Clamp to the actual remaining payload.
2030 len = std::min(len, remaining_data_length_); 2034 len = std::min(len, remaining_data_length_);
2031 2035
2032 size_t processed_bytes = 0; 2036 if (altsvc_scratch_.buffer.get() == nullptr) {
2033 size_t processing = 0; 2037 altsvc_scratch_.buffer.reset(
2034 size_t bytes_remaining; 2038 new char[current_frame_length_ - GetControlFrameHeaderSize()]);
2035 char* buffer; 2039 altsvc_scratch_.buffer_length = 0;
2036 size_t* buffer_len; 2040 }
2037 2041 memcpy(altsvc_scratch_.buffer.get() + altsvc_scratch_.buffer_length, data,
2038 while (len > 0) { 2042 len);
2039 if (altsvc_scratch_.pid_len == 0) { 2043 altsvc_scratch_.buffer_length += len;
2040 // The size of the frame up to the PID_LEN field. 2044 remaining_data_length_ -= len;
2041 size_t fixed_len_portion = GetAltSvcMinimumSize() - 1; 2045 if (remaining_data_length_ > 0) {
2042 bytes_remaining = fixed_len_portion - current_frame_buffer_length_; 2046 return len;
2043 processing = std::min(len, bytes_remaining);
2044 // Buffer the new ALTSVC bytes we got.
2045 UpdateCurrentFrameBuffer(&data, &len, processing);
2046
2047 // Do we have enough to parse the length of the protocol id?
2048 if (current_frame_buffer_length_ == fixed_len_portion) {
2049 // Parse out the max age, port, and pid_len.
2050 SpdyFrameReader reader(current_frame_buffer_.get(),
2051 current_frame_buffer_length_);
2052 reader.Seek(GetControlFrameHeaderSize()); // Seek past frame header.
2053 bool successful_read = reader.ReadUInt32(&altsvc_scratch_.max_age);
2054 reader.ReadUInt16(&altsvc_scratch_.port);
2055 reader.Seek(1); // Reserved byte.
2056 successful_read = successful_read &&
2057 reader.ReadUInt8(&altsvc_scratch_.pid_len);
2058 DCHECK(successful_read);
2059 // Sanity check length value.
2060 if (altsvc_scratch_.pid_len == 0 ||
2061 GetAltSvcMinimumSize() + altsvc_scratch_.pid_len >=
2062 current_frame_length_) {
2063 set_error(SPDY_INVALID_CONTROL_FRAME);
2064 return 0;
2065 }
2066 altsvc_scratch_.protocol_id.reset(
2067 new char[size_t(altsvc_scratch_.pid_len)]);
2068 }
2069 processed_bytes += processing;
2070 continue;
2071 } else if (altsvc_scratch_.pid_buf_len < altsvc_scratch_.pid_len) {
2072 // Buffer protocol id field as in comes in.
2073 buffer = altsvc_scratch_.protocol_id.get();
2074 buffer_len = &altsvc_scratch_.pid_buf_len;
2075 bytes_remaining = altsvc_scratch_.pid_len - altsvc_scratch_.pid_buf_len;
2076 } else if (altsvc_scratch_.host_len == 0) {
2077 // Parse out the host length.
2078 processing = 1;
2079 altsvc_scratch_.host_len = *reinterpret_cast<const uint8*>(data);
2080 // Sanity check length value.
2081 if (GetAltSvcMinimumSize() + altsvc_scratch_.pid_len +
2082 altsvc_scratch_.host_len > current_frame_length_) {
2083 set_error(SPDY_INVALID_CONTROL_FRAME);
2084 return 0;
2085 }
2086 altsvc_scratch_.host.reset(new char[altsvc_scratch_.host_len]);
2087 // Once we have host length, we can also determine the origin length
2088 // by process of elimination.
2089 altsvc_scratch_.origin_len = current_frame_length_ -
2090 GetAltSvcMinimumSize() -
2091 altsvc_scratch_.pid_len -
2092 altsvc_scratch_.host_len;
2093 if (altsvc_scratch_.origin_len > 0) {
2094 altsvc_scratch_.origin.reset(new char[altsvc_scratch_.origin_len]);
2095 }
2096 data += processing;
2097 processed_bytes += processing;
2098 len -= processing;
2099 continue;
2100 } else if (altsvc_scratch_.host_buf_len < altsvc_scratch_.host_len) {
2101 // Buffer host field as it comes in.
2102 // TODO(mlavan): check formatting for host and origin
2103 buffer = altsvc_scratch_.host.get();
2104 buffer_len = &altsvc_scratch_.host_buf_len;
2105 bytes_remaining = altsvc_scratch_.host_len - altsvc_scratch_.host_buf_len;
2106 } else {
2107 // Buffer (optional) origin field as it comes in.
2108 if (altsvc_scratch_.origin_len <= 0) {
2109 set_error(SPDY_INVALID_CONTROL_FRAME);
2110 return 0;
2111 }
2112 buffer = altsvc_scratch_.origin.get();
2113 buffer_len = &altsvc_scratch_.origin_buf_len;
2114 bytes_remaining = remaining_data_length_ -
2115 processed_bytes -
2116 altsvc_scratch_.origin_buf_len;
2117 if (len > bytes_remaining) {
2118 // This is our last field; there shouldn't be any more bytes.
2119 set_error(SPDY_INVALID_CONTROL_FRAME);
2120 return 0;
2121 }
2122 }
2123
2124 // Copy data bytes into the appropriate field.
2125 processing = std::min(len, bytes_remaining);
2126 memcpy(buffer + *buffer_len,
2127 data,
2128 processing);
2129 *buffer_len += processing;
2130 data += processing;
2131 processed_bytes += processing;
2132 len -= processing;
2133 } 2047 }
2134 2048
2135 remaining_data_length_ -= processed_bytes; 2049 SpdyFrameReader reader(altsvc_scratch_.buffer.get(),
2136 if (remaining_data_length_ == 0) { 2050 altsvc_scratch_.buffer_length);
2137 visitor_->OnAltSvc(current_frame_stream_id_, 2051 StringPiece origin;
2138 altsvc_scratch_.max_age, 2052 bool successful_read = reader.ReadStringPiece16(&origin);
2139 altsvc_scratch_.port, 2053 if (!successful_read) {
2140 StringPiece(altsvc_scratch_.protocol_id.get(), 2054 set_error(SPDY_INVALID_CONTROL_FRAME);
2141 altsvc_scratch_.pid_len), 2055 return 0;
2142 StringPiece(altsvc_scratch_.host.get(), 2056 }
2143 altsvc_scratch_.host_len), 2057 StringPiece value(altsvc_scratch_.buffer.get() + reader.GetBytesConsumed(),
2144 StringPiece(altsvc_scratch_.origin.get(), 2058 altsvc_scratch_.buffer_length - reader.GetBytesConsumed());
2145 altsvc_scratch_.origin_len)); 2059
2146 CHANGE_STATE(SPDY_AUTO_RESET); 2060 string protocol_id;
2061 string host;
2062 uint16 port;
2063 uint32 max_age;
2064 double p;
2065 bool success = SpdyAltSvcWireFormat::ParseHeaderFieldValue(
2066 value, &protocol_id, &host, &port, &max_age, &p);
2067 if (!success || protocol_id.length() == 0) {
2068 set_error(SPDY_INVALID_CONTROL_FRAME);
2069 return 0;
2147 } 2070 }
2148 2071
2149 return processed_bytes; 2072 // TODO(bnc): Pass on |p|.
2073 visitor_->OnAltSvc(current_frame_stream_id_, max_age, port, protocol_id, host,
2074 origin);
2075 CHANGE_STATE(SPDY_AUTO_RESET);
2076 return len;
2150 } 2077 }
2151 2078
2152 size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) { 2079 size_t SpdyFramer::ProcessDataFramePaddingLength(const char* data, size_t len) {
2153 DCHECK_EQ(SPDY_READ_DATA_FRAME_PADDING_LENGTH, state_); 2080 DCHECK_EQ(SPDY_READ_DATA_FRAME_PADDING_LENGTH, state_);
2154 DCHECK_EQ(0u, remaining_padding_payload_length_); 2081 DCHECK_EQ(0u, remaining_padding_payload_length_);
2155 DCHECK_EQ(DATA, current_frame_type_); 2082 DCHECK_EQ(DATA, current_frame_type_);
2156 2083
2157 size_t original_len = len; 2084 size_t original_len = len;
2158 if (current_frame_flags_ & DATA_FLAG_PADDED) { 2085 if (current_frame_flags_ & DATA_FLAG_PADDED) {
2159 if (len != 0) { 2086 if (len != 0) {
(...skipping 680 matching lines...) Expand 10 before | Expand all | Expand 10 after
2840 builder.BeginNewFrame(*this, CONTINUATION, flags, 2767 builder.BeginNewFrame(*this, CONTINUATION, flags,
2841 continuation.stream_id()); 2768 continuation.stream_id());
2842 DCHECK_EQ(GetContinuationMinimumSize(), builder.length()); 2769 DCHECK_EQ(GetContinuationMinimumSize(), builder.length());
2843 2770
2844 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2771 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2845 return builder.take(); 2772 return builder.take();
2846 } 2773 }
2847 2774
2848 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) { 2775 SpdyFrame* SpdyFramer::SerializeAltSvc(const SpdyAltSvcIR& altsvc) {
2849 DCHECK_LT(SPDY3, protocol_version()); 2776 DCHECK_LT(SPDY3, protocol_version());
2777
2850 size_t size = GetAltSvcMinimumSize(); 2778 size_t size = GetAltSvcMinimumSize();
2851 size += altsvc.protocol_id().length();
2852 size += altsvc.host().length();
2853 size += altsvc.origin().length(); 2779 size += altsvc.origin().length();
2780 // TODO(bnc): Add probability to SpdyAltSvcIR and pass it on.
2781 string value = SpdyAltSvcWireFormat::SerializeHeaderFieldValue(
2782 altsvc.protocol_id(), altsvc.host(), altsvc.port(), altsvc.max_age(),
2783 1.0);
2784 size += value.length();
2854 2785
2855 SpdyFrameBuilder builder(size, protocol_version()); 2786 SpdyFrameBuilder builder(size, protocol_version());
2856 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id()); 2787 builder.BeginNewFrame(*this, ALTSVC, kNoFlags, altsvc.stream_id());
2857 2788
2858 // TODO(bnc): http://crbug.com/438263 2789 builder.WriteUInt16(altsvc.origin().length());
2859 // Update the binary format here to the new text-based payload format.
2860 builder.WriteUInt32(altsvc.max_age());
2861 builder.WriteUInt16(altsvc.port());
2862 builder.WriteUInt8(0); // Reserved.
2863 builder.WriteUInt8(static_cast<uint8>(altsvc.protocol_id().length()));
2864 builder.WriteBytes(altsvc.protocol_id().data(),
2865 altsvc.protocol_id().length());
2866 builder.WriteUInt8(static_cast<uint8>(altsvc.host().length()));
2867 builder.WriteBytes(altsvc.host().data(), altsvc.host().length());
2868 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length()); 2790 builder.WriteBytes(altsvc.origin().data(), altsvc.origin().length());
2791 builder.WriteBytes(value.data(), value.length());
2869 DCHECK_LT(GetAltSvcMinimumSize(), builder.length()); 2792 DCHECK_LT(GetAltSvcMinimumSize(), builder.length());
2870 return builder.take(); 2793 return builder.take();
2871 } 2794 }
2872 2795
2873 SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) const { 2796 SpdyFrame* SpdyFramer::SerializePriority(const SpdyPriorityIR& priority) const {
2874 DCHECK_LT(SPDY3, protocol_version()); 2797 DCHECK_LT(SPDY3, protocol_version());
2875 size_t size = GetPrioritySize(); 2798 size_t size = GetPrioritySize();
2876 2799
2877 SpdyFrameBuilder builder(size, protocol_version()); 2800 SpdyFrameBuilder builder(size, protocol_version());
2878 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id()); 2801 builder.BeginNewFrame(*this, PRIORITY, kNoFlags, priority.stream_id());
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after
3292 #else 3215 #else
3293 WriteHeaderBlockToZ(&frame.name_value_block(), compressor); 3216 WriteHeaderBlockToZ(&frame.name_value_block(), compressor);
3294 #endif // defined(USE_SYSTEM_ZLIB) 3217 #endif // defined(USE_SYSTEM_ZLIB)
3295 3218
3296 int compressed_size = compressed_max_size - compressor->avail_out; 3219 int compressed_size = compressed_max_size - compressor->avail_out;
3297 builder->Seek(compressed_size); 3220 builder->Seek(compressed_size);
3298 builder->RewriteLength(*this); 3221 builder->RewriteLength(*this);
3299 } 3222 }
3300 3223
3301 } // namespace net 3224 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698