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

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

Issue 287003011: Initial support for HTTP/2 dependencies and weights (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Constants for dependency + weight payload size. Created 6 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 | Annotate | Revision Log
« 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 "base/lazy_instance.h" 7 #include "base/lazy_instance.h"
8 #include "base/memory/scoped_ptr.h" 8 #include "base/memory/scoped_ptr.h"
9 #include "base/metrics/stats_counters.h" 9 #include "base/metrics/stats_counters.h"
10 #include "base/third_party/valgrind/memcheck.h" 10 #include "base/third_party/valgrind/memcheck.h"
(...skipping 29 matching lines...) Expand all
40 const uLong v3_dictionary_id; 40 const uLong v3_dictionary_id;
41 }; 41 };
42 42
43 // Adler ID for the SPDY header compressor dictionaries. Note that they are 43 // Adler ID for the SPDY header compressor dictionaries. Note that they are
44 // initialized lazily to avoid static initializers. 44 // initialized lazily to avoid static initializers.
45 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids; 45 base::LazyInstance<DictionaryIds>::Leaky g_dictionary_ids;
46 46
47 // Used to indicate no flags in a SPDY flags field. 47 // Used to indicate no flags in a SPDY flags field.
48 const uint8 kNoFlags = 0; 48 const uint8 kNoFlags = 0;
49 49
50 // Wire sizes of priority payloads.
51 const size_t kPriorityDependencyPayloadSize = 4;
52 const size_t kPriorityWeightPayloadSize = 1;
53
50 } // namespace 54 } // namespace
51 55
52 const SpdyStreamId SpdyFramer::kInvalidStream = -1; 56 const SpdyStreamId SpdyFramer::kInvalidStream = -1;
53 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024; 57 const size_t SpdyFramer::kHeaderDataChunkMaxSize = 1024;
54 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for 58 // largest control frame, which is SYN_STREAM. See GetSynStreamMinimumSize() for
55 // calculation details. 59 // calculation details.
56 const size_t SpdyFramer::kControlFrameBufferSize = 18; 60 const size_t SpdyFramer::kControlFrameBufferSize = 18;
57 61
58 #ifdef DEBUG_SPDY_STATE_CHANGES 62 #ifdef DEBUG_SPDY_STATE_CHANGES
59 #define CHANGE_STATE(newstate) \ 63 #define CHANGE_STATE(newstate) \
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
176 180
177 size_t SpdyFramer::GetSynStreamMinimumSize() const { 181 size_t SpdyFramer::GetSynStreamMinimumSize() const {
178 // Size, in bytes, of a SYN_STREAM frame not including the variable-length 182 // Size, in bytes, of a SYN_STREAM frame not including the variable-length
179 // name-value block. 183 // name-value block.
180 if (protocol_version() <= SPDY3) { 184 if (protocol_version() <= SPDY3) {
181 // Calculated as: 185 // Calculated as:
182 // control frame header + 2 * 4 (stream IDs) + 1 (priority) 186 // control frame header + 2 * 4 (stream IDs) + 1 (priority)
183 // + 1 (unused, was credential slot) 187 // + 1 (unused, was credential slot)
184 return GetControlFrameHeaderSize() + 10; 188 return GetControlFrameHeaderSize() + 10;
185 } else { 189 } else {
186 // Calculated as: 190 return GetControlFrameHeaderSize() +
187 // frame prefix + 4 (priority) 191 kPriorityDependencyPayloadSize +
188 return GetControlFrameHeaderSize() + 4; 192 kPriorityWeightPayloadSize;
189 } 193 }
190 } 194 }
191 195
192 size_t SpdyFramer::GetSynReplyMinimumSize() const { 196 size_t SpdyFramer::GetSynReplyMinimumSize() const {
193 // Size, in bytes, of a SYN_REPLY frame not including the variable-length 197 // Size, in bytes, of a SYN_REPLY frame not including the variable-length
194 // name-value block. 198 // name-value block.
195 size_t size = GetControlFrameHeaderSize(); 199 size_t size = GetControlFrameHeaderSize();
196 if (protocol_version() <= SPDY3) { 200 if (protocol_version() <= SPDY3) {
197 // Calculated as: 201 // Calculated as:
198 // control frame header + 4 (stream IDs) 202 // control frame header + 4 (stream IDs)
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 // (optional) Origin fields, all of which can vary in length. 320 // (optional) Origin fields, all of which can vary in length.
317 // Note that this gives a lower bound on the frame size rather than a true 321 // Note that this gives a lower bound on the frame size rather than a true
318 // minimum; the actual frame should always be larger than this. 322 // minimum; the actual frame should always be larger than this.
319 // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte) 323 // Calculated as frame prefix + 4 (max-age) + 2 (port) + 1 (reserved byte)
320 // + 1 (pid_len) + 1 (host_len). 324 // + 1 (pid_len) + 1 (host_len).
321 return GetControlFrameHeaderSize() + 9; 325 return GetControlFrameHeaderSize() + 9;
322 } 326 }
323 327
324 size_t SpdyFramer::GetPrioritySize() const { 328 size_t SpdyFramer::GetPrioritySize() const {
325 // Size, in bytes, of a PRIORITY frame. 329 // Size, in bytes, of a PRIORITY frame.
326 // Calculated as frame prefix + 4 (stream dependency) + 1 (weight) 330 return GetControlFrameHeaderSize() +
327 return GetControlFrameHeaderSize() + 5; 331 kPriorityDependencyPayloadSize +
332 kPriorityWeightPayloadSize;
328 } 333 }
329 334
330 size_t SpdyFramer::GetFrameMinimumSize() const { 335 size_t SpdyFramer::GetFrameMinimumSize() const {
331 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize()); 336 return std::min(GetDataFrameMinimumSize(), GetControlFrameHeaderSize());
332 } 337 }
333 338
334 size_t SpdyFramer::GetFrameMaximumSize() const { 339 size_t SpdyFramer::GetFrameMaximumSize() const {
335 return SpdyConstants::GetFrameMaximumSize(protocol_version()); 340 return SpdyConstants::GetFrameMaximumSize(protocol_version());
336 } 341 }
337 342
(...skipping 702 matching lines...) Expand 10 before | Expand all | Expand 10 after
1040 syn_frame_processed_ = true; 1045 syn_frame_processed_ = true;
1041 frame_size_without_variable_data = GetSynReplyMinimumSize(); 1046 frame_size_without_variable_data = GetSynReplyMinimumSize();
1042 break; 1047 break;
1043 case SETTINGS: 1048 case SETTINGS:
1044 frame_size_without_variable_data = GetSettingsMinimumSize(); 1049 frame_size_without_variable_data = GetSettingsMinimumSize();
1045 break; 1050 break;
1046 case HEADERS: 1051 case HEADERS:
1047 frame_size_without_variable_data = GetHeadersMinimumSize(); 1052 frame_size_without_variable_data = GetHeadersMinimumSize();
1048 if (protocol_version() > SPDY3 && 1053 if (protocol_version() > SPDY3 &&
1049 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { 1054 current_frame_flags_ & HEADERS_FLAG_PRIORITY) {
1050 frame_size_without_variable_data += 4; // priority 1055 frame_size_without_variable_data +=
1056 kPriorityDependencyPayloadSize +
1057 kPriorityWeightPayloadSize;
1051 } 1058 }
1052 break; 1059 break;
1053 case PUSH_PROMISE: 1060 case PUSH_PROMISE:
1054 frame_size_without_variable_data = GetPushPromiseMinimumSize(); 1061 frame_size_without_variable_data = GetPushPromiseMinimumSize();
1055 break; 1062 break;
1056 case CONTINUATION: 1063 case CONTINUATION:
1057 frame_size_without_variable_data = GetContinuationMinimumSize(); 1064 frame_size_without_variable_data = GetContinuationMinimumSize();
1058 break; 1065 break;
1059 default: 1066 default:
1060 frame_size_without_variable_data = -1; 1067 frame_size_without_variable_data = -1;
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after
1407 if (protocol_version() > SPDY3 && 1414 if (protocol_version() > SPDY3 &&
1408 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && 1415 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) &&
1409 current_frame_type_ == HEADERS) { 1416 current_frame_type_ == HEADERS) {
1410 expect_continuation_ = current_frame_stream_id_; 1417 expect_continuation_ = current_frame_stream_id_;
1411 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; 1418 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN;
1412 } 1419 }
1413 const bool has_priority = 1420 const bool has_priority =
1414 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; 1421 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0;
1415 uint32 priority = 0; 1422 uint32 priority = 0;
1416 if (protocol_version() > SPDY3 && has_priority) { 1423 if (protocol_version() > SPDY3 && has_priority) {
1417 successful_read = reader.ReadUInt31(&priority); 1424 // TODO(jgraettinger): Process dependency rather than ignoring it.
1418 DCHECK(successful_read); 1425 reader.Seek(kPriorityDependencyPayloadSize);
1426 uint8 weight = 0;
1427 successful_read = reader.ReadUInt8(&weight);
1428 if (successful_read) {
1429 priority = MapWeightToPriority(weight);
1430 }
1419 } 1431 }
1420 DCHECK(reader.IsDoneReading()); 1432 DCHECK(reader.IsDoneReading());
1421 if (debug_visitor_) { 1433 if (debug_visitor_) {
1422 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. 1434 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM.
1423 SpdyFrameType reported_type = current_frame_type_; 1435 SpdyFrameType reported_type = current_frame_type_;
1424 if (protocol_version() > SPDY3 && has_priority) { 1436 if (protocol_version() > SPDY3 && has_priority) {
1425 reported_type = SYN_STREAM; 1437 reported_type = SYN_STREAM;
1426 } 1438 }
1427 debug_visitor_->OnReceiveCompressedFrame( 1439 debug_visitor_->OnReceiveCompressedFrame(
1428 current_frame_stream_id_, 1440 current_frame_stream_id_,
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after
2369 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); 2381 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags);
2370 builder.WriteUInt32(syn_stream.stream_id()); 2382 builder.WriteUInt32(syn_stream.stream_id());
2371 builder.WriteUInt32(syn_stream.associated_to_stream_id()); 2383 builder.WriteUInt32(syn_stream.associated_to_stream_id());
2372 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); 2384 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5));
2373 builder.WriteUInt8(0); // Unused byte where credential slot used to be. 2385 builder.WriteUInt8(0); // Unused byte where credential slot used to be.
2374 } else { 2386 } else {
2375 builder.BeginNewFrame(*this, 2387 builder.BeginNewFrame(*this,
2376 HEADERS, 2388 HEADERS,
2377 flags, 2389 flags,
2378 syn_stream.stream_id()); 2390 syn_stream.stream_id());
2379 builder.WriteUInt32(priority); 2391 // TODO(jgraettinger): Plumb priorities and stream dependencies.
2392 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID.
2393 builder.WriteUInt8(MapPriorityToWeight(priority));
2380 } 2394 }
2381 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); 2395 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length());
2382 if (protocol_version() > SPDY3) { 2396 if (protocol_version() > SPDY3) {
2383 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); 2397 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size());
2384 } else { 2398 } else {
2385 SerializeNameValueBlock(&builder, syn_stream); 2399 SerializeNameValueBlock(&builder, syn_stream);
2386 } 2400 }
2387 2401
2388 if (debug_visitor_) { 2402 if (debug_visitor_) {
2389 const size_t payload_len = protocol_version() > SPDY3 ? 2403 const size_t payload_len = protocol_version() > SPDY3 ?
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
2657 SpdyFrameBuilder builder(size, protocol_version()); 2671 SpdyFrameBuilder builder(size, protocol_version());
2658 if (protocol_version() <= SPDY3) { 2672 if (protocol_version() <= SPDY3) {
2659 builder.WriteControlFrameHeader(*this, HEADERS, flags); 2673 builder.WriteControlFrameHeader(*this, HEADERS, flags);
2660 builder.WriteUInt32(headers.stream_id()); 2674 builder.WriteUInt32(headers.stream_id());
2661 } else { 2675 } else {
2662 builder.BeginNewFrame(*this, 2676 builder.BeginNewFrame(*this,
2663 HEADERS, 2677 HEADERS,
2664 flags, 2678 flags,
2665 headers.stream_id()); 2679 headers.stream_id());
2666 if (headers.has_priority()) { 2680 if (headers.has_priority()) {
2667 builder.WriteUInt32(priority); 2681 // TODO(jgraettinger): Plumb priorities and stream dependencies.
2682 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID.
2683 builder.WriteUInt8(MapPriorityToWeight(priority));
2668 } 2684 }
2669 } 2685 }
2670 if (protocol_version() <= SPDY2) { 2686 if (protocol_version() <= SPDY2) {
2671 builder.WriteUInt16(0); // Unused. 2687 builder.WriteUInt16(0); // Unused.
2672 } 2688 }
2673 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); 2689 DCHECK_EQ(GetHeadersMinimumSize(), builder.length());
2674 2690
2675 if (protocol_version() > SPDY3) { 2691 if (protocol_version() > SPDY3) {
2676 WritePayloadWithContinuation(&builder, 2692 WritePayloadWithContinuation(&builder,
2677 hpack_encoding, 2693 hpack_encoding,
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after
3048 } 3064 }
3049 3065
3050 HpackDecoder* SpdyFramer::GetHpackDecoder() { 3066 HpackDecoder* SpdyFramer::GetHpackDecoder() {
3051 DCHECK_LT(SPDY3, spdy_version_); 3067 DCHECK_LT(SPDY3, spdy_version_);
3052 if (hpack_decoder_.get() == NULL) { 3068 if (hpack_decoder_.get() == NULL) {
3053 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable())); 3069 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
3054 } 3070 }
3055 return hpack_decoder_.get(); 3071 return hpack_decoder_.get();
3056 } 3072 }
3057 3073
3074 uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
3075 const float kSteps = 255.9f / 7.f;
3076 return static_cast<uint8>(kSteps * (7.f - priority));
3077 }
3078
3079 SpdyPriority SpdyFramer::MapWeightToPriority(uint8 weight) {
3080 const float kSteps = 255.9f / 7.f;
3081 return static_cast<SpdyPriority>(7.f - weight / kSteps);
3082 }
3083
3058 // Incrementally decompress the control frame's header block, feeding the 3084 // Incrementally decompress the control frame's header block, feeding the
3059 // result to the visitor in chunks. Continue this until the visitor 3085 // result to the visitor in chunks. Continue this until the visitor
3060 // indicates that it cannot process any more data, or (more commonly) we 3086 // indicates that it cannot process any more data, or (more commonly) we
3061 // run out of data to deliver. 3087 // run out of data to deliver.
3062 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( 3088 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData(
3063 SpdyStreamId stream_id, 3089 SpdyStreamId stream_id,
3064 const char* data, 3090 const char* data,
3065 size_t len) { 3091 size_t len) {
3066 // Get a decompressor or set error. 3092 // Get a decompressor or set error.
3067 z_stream* decomp = GetHeaderDecompressor(); 3093 z_stream* decomp = GetHeaderDecompressor();
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
3234 builder->Seek(compressed_size); 3260 builder->Seek(compressed_size);
3235 builder->RewriteLength(*this); 3261 builder->RewriteLength(*this);
3236 3262
3237 pre_compress_bytes.Add(uncompressed_len); 3263 pre_compress_bytes.Add(uncompressed_len);
3238 post_compress_bytes.Add(compressed_size); 3264 post_compress_bytes.Add(compressed_size);
3239 3265
3240 compressed_frames.Increment(); 3266 compressed_frames.Increment();
3241 } 3267 }
3242 3268
3243 } // namespace net 3269 } // 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