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 "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 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
177 size_t SpdyFramer::GetSynStreamMinimumSize() const { | 177 size_t SpdyFramer::GetSynStreamMinimumSize() const { |
178 // Size, in bytes, of a SYN_STREAM frame not including the variable-length | 178 // Size, in bytes, of a SYN_STREAM frame not including the variable-length |
179 // name-value block. | 179 // name-value block. |
180 if (protocol_version() <= SPDY3) { | 180 if (protocol_version() <= SPDY3) { |
181 // Calculated as: | 181 // Calculated as: |
182 // control frame header + 2 * 4 (stream IDs) + 1 (priority) | 182 // control frame header + 2 * 4 (stream IDs) + 1 (priority) |
183 // + 1 (unused, was credential slot) | 183 // + 1 (unused, was credential slot) |
184 return GetControlFrameHeaderSize() + 10; | 184 return GetControlFrameHeaderSize() + 10; |
185 } else { | 185 } else { |
186 // Calculated as: | 186 // Calculated as: |
187 // frame prefix + 4 (priority) | 187 // frame prefix + 5 (priority) |
188 return GetControlFrameHeaderSize() + 4; | 188 return GetControlFrameHeaderSize() + 5; |
Ryan Hamilton
2014/05/19 22:56:41
I'm not terribly in love with the magic number her
Johnny
2014/05/19 23:27:17
Done. Though, now this particularly calls attentio
| |
189 } | 189 } |
190 } | 190 } |
191 | 191 |
192 size_t SpdyFramer::GetSynReplyMinimumSize() const { | 192 size_t SpdyFramer::GetSynReplyMinimumSize() const { |
193 // Size, in bytes, of a SYN_REPLY frame not including the variable-length | 193 // Size, in bytes, of a SYN_REPLY frame not including the variable-length |
194 // name-value block. | 194 // name-value block. |
195 size_t size = GetControlFrameHeaderSize(); | 195 size_t size = GetControlFrameHeaderSize(); |
196 if (protocol_version() <= SPDY3) { | 196 if (protocol_version() <= SPDY3) { |
197 // Calculated as: | 197 // Calculated as: |
198 // control frame header + 4 (stream IDs) | 198 // control frame header + 4 (stream IDs) |
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1040 syn_frame_processed_ = true; | 1040 syn_frame_processed_ = true; |
1041 frame_size_without_variable_data = GetSynReplyMinimumSize(); | 1041 frame_size_without_variable_data = GetSynReplyMinimumSize(); |
1042 break; | 1042 break; |
1043 case SETTINGS: | 1043 case SETTINGS: |
1044 frame_size_without_variable_data = GetSettingsMinimumSize(); | 1044 frame_size_without_variable_data = GetSettingsMinimumSize(); |
1045 break; | 1045 break; |
1046 case HEADERS: | 1046 case HEADERS: |
1047 frame_size_without_variable_data = GetHeadersMinimumSize(); | 1047 frame_size_without_variable_data = GetHeadersMinimumSize(); |
1048 if (protocol_version() > SPDY3 && | 1048 if (protocol_version() > SPDY3 && |
1049 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { | 1049 current_frame_flags_ & HEADERS_FLAG_PRIORITY) { |
1050 frame_size_without_variable_data += 4; // priority | 1050 frame_size_without_variable_data += 5; // priority |
1051 } | 1051 } |
1052 break; | 1052 break; |
1053 case PUSH_PROMISE: | 1053 case PUSH_PROMISE: |
1054 frame_size_without_variable_data = GetPushPromiseMinimumSize(); | 1054 frame_size_without_variable_data = GetPushPromiseMinimumSize(); |
1055 break; | 1055 break; |
1056 case CONTINUATION: | 1056 case CONTINUATION: |
1057 frame_size_without_variable_data = GetContinuationMinimumSize(); | 1057 frame_size_without_variable_data = GetContinuationMinimumSize(); |
1058 break; | 1058 break; |
1059 default: | 1059 default: |
1060 frame_size_without_variable_data = -1; | 1060 frame_size_without_variable_data = -1; |
(...skipping 346 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1407 if (protocol_version() > SPDY3 && | 1407 if (protocol_version() > SPDY3 && |
1408 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && | 1408 !(current_frame_flags_ & HEADERS_FLAG_END_HEADERS) && |
1409 current_frame_type_ == HEADERS) { | 1409 current_frame_type_ == HEADERS) { |
1410 expect_continuation_ = current_frame_stream_id_; | 1410 expect_continuation_ = current_frame_stream_id_; |
1411 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; | 1411 end_stream_when_done_ = current_frame_flags_ & CONTROL_FLAG_FIN; |
1412 } | 1412 } |
1413 const bool has_priority = | 1413 const bool has_priority = |
1414 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; | 1414 (current_frame_flags_ & HEADERS_FLAG_PRIORITY) != 0; |
1415 uint32 priority = 0; | 1415 uint32 priority = 0; |
1416 if (protocol_version() > SPDY3 && has_priority) { | 1416 if (protocol_version() > SPDY3 && has_priority) { |
1417 successful_read = reader.ReadUInt31(&priority); | 1417 // TODO(jgraettinger): Process dependency rather than ignoring it. |
1418 DCHECK(successful_read); | 1418 reader.Seek(4); |
1419 uint8 weight = 0; | |
1420 successful_read = reader.ReadUInt8(&weight); | |
1421 if (successful_read) { | |
1422 priority = MapWeightToPriority(weight); | |
1423 } | |
1419 } | 1424 } |
1420 DCHECK(reader.IsDoneReading()); | 1425 DCHECK(reader.IsDoneReading()); |
1421 if (debug_visitor_) { | 1426 if (debug_visitor_) { |
1422 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. | 1427 // SPDY 4 reports HEADERS with PRIORITY as SYN_STREAM. |
1423 SpdyFrameType reported_type = current_frame_type_; | 1428 SpdyFrameType reported_type = current_frame_type_; |
1424 if (protocol_version() > SPDY3 && has_priority) { | 1429 if (protocol_version() > SPDY3 && has_priority) { |
1425 reported_type = SYN_STREAM; | 1430 reported_type = SYN_STREAM; |
1426 } | 1431 } |
1427 debug_visitor_->OnReceiveCompressedFrame( | 1432 debug_visitor_->OnReceiveCompressedFrame( |
1428 current_frame_stream_id_, | 1433 current_frame_stream_id_, |
(...skipping 940 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2369 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); | 2374 builder.WriteControlFrameHeader(*this, SYN_STREAM, flags); |
2370 builder.WriteUInt32(syn_stream.stream_id()); | 2375 builder.WriteUInt32(syn_stream.stream_id()); |
2371 builder.WriteUInt32(syn_stream.associated_to_stream_id()); | 2376 builder.WriteUInt32(syn_stream.associated_to_stream_id()); |
2372 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); | 2377 builder.WriteUInt8(priority << ((protocol_version() <= SPDY2) ? 6 : 5)); |
2373 builder.WriteUInt8(0); // Unused byte where credential slot used to be. | 2378 builder.WriteUInt8(0); // Unused byte where credential slot used to be. |
2374 } else { | 2379 } else { |
2375 builder.BeginNewFrame(*this, | 2380 builder.BeginNewFrame(*this, |
2376 HEADERS, | 2381 HEADERS, |
2377 flags, | 2382 flags, |
2378 syn_stream.stream_id()); | 2383 syn_stream.stream_id()); |
2379 builder.WriteUInt32(priority); | 2384 // TODO(jgraettinger): Plumb priorities and stream dependencies. |
2385 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. | |
2386 builder.WriteUInt8(MapPriorityToWeight(priority)); | |
2380 } | 2387 } |
2381 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); | 2388 DCHECK_EQ(GetSynStreamMinimumSize(), builder.length()); |
2382 if (protocol_version() > SPDY3) { | 2389 if (protocol_version() > SPDY3) { |
2383 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); | 2390 builder.WriteBytes(&hpack_encoding[0], hpack_encoding.size()); |
2384 } else { | 2391 } else { |
2385 SerializeNameValueBlock(&builder, syn_stream); | 2392 SerializeNameValueBlock(&builder, syn_stream); |
2386 } | 2393 } |
2387 | 2394 |
2388 if (debug_visitor_) { | 2395 if (debug_visitor_) { |
2389 const size_t payload_len = protocol_version() > SPDY3 ? | 2396 const size_t payload_len = protocol_version() > SPDY3 ? |
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2657 SpdyFrameBuilder builder(size, protocol_version()); | 2664 SpdyFrameBuilder builder(size, protocol_version()); |
2658 if (protocol_version() <= SPDY3) { | 2665 if (protocol_version() <= SPDY3) { |
2659 builder.WriteControlFrameHeader(*this, HEADERS, flags); | 2666 builder.WriteControlFrameHeader(*this, HEADERS, flags); |
2660 builder.WriteUInt32(headers.stream_id()); | 2667 builder.WriteUInt32(headers.stream_id()); |
2661 } else { | 2668 } else { |
2662 builder.BeginNewFrame(*this, | 2669 builder.BeginNewFrame(*this, |
2663 HEADERS, | 2670 HEADERS, |
2664 flags, | 2671 flags, |
2665 headers.stream_id()); | 2672 headers.stream_id()); |
2666 if (headers.has_priority()) { | 2673 if (headers.has_priority()) { |
2667 builder.WriteUInt32(priority); | 2674 // TODO(jgraettinger): Plumb priorities and stream dependencies. |
2675 builder.WriteUInt32(0); // Non-exclusive bit and root stream ID. | |
2676 builder.WriteUInt8(MapPriorityToWeight(priority)); | |
2668 } | 2677 } |
2669 } | 2678 } |
2670 if (protocol_version() <= SPDY2) { | 2679 if (protocol_version() <= SPDY2) { |
2671 builder.WriteUInt16(0); // Unused. | 2680 builder.WriteUInt16(0); // Unused. |
2672 } | 2681 } |
2673 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); | 2682 DCHECK_EQ(GetHeadersMinimumSize(), builder.length()); |
2674 | 2683 |
2675 if (protocol_version() > SPDY3) { | 2684 if (protocol_version() > SPDY3) { |
2676 WritePayloadWithContinuation(&builder, | 2685 WritePayloadWithContinuation(&builder, |
2677 hpack_encoding, | 2686 hpack_encoding, |
(...skipping 370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3048 } | 3057 } |
3049 | 3058 |
3050 HpackDecoder* SpdyFramer::GetHpackDecoder() { | 3059 HpackDecoder* SpdyFramer::GetHpackDecoder() { |
3051 DCHECK_LT(SPDY3, spdy_version_); | 3060 DCHECK_LT(SPDY3, spdy_version_); |
3052 if (hpack_decoder_.get() == NULL) { | 3061 if (hpack_decoder_.get() == NULL) { |
3053 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable())); | 3062 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable())); |
3054 } | 3063 } |
3055 return hpack_decoder_.get(); | 3064 return hpack_decoder_.get(); |
3056 } | 3065 } |
3057 | 3066 |
3067 uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) { | |
3068 const float kSteps = 255.9f / 7.f; | |
3069 return static_cast<uint8>(kSteps * (7.f - priority)); | |
3070 } | |
3071 | |
3072 SpdyPriority SpdyFramer::MapWeightToPriority(uint8 weight) { | |
3073 const float kSteps = 255.9f / 7.f; | |
3074 return static_cast<SpdyPriority>(7.f - weight / kSteps); | |
3075 } | |
3076 | |
3058 // Incrementally decompress the control frame's header block, feeding the | 3077 // Incrementally decompress the control frame's header block, feeding the |
3059 // result to the visitor in chunks. Continue this until the visitor | 3078 // result to the visitor in chunks. Continue this until the visitor |
3060 // indicates that it cannot process any more data, or (more commonly) we | 3079 // indicates that it cannot process any more data, or (more commonly) we |
3061 // run out of data to deliver. | 3080 // run out of data to deliver. |
3062 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( | 3081 bool SpdyFramer::IncrementallyDecompressControlFrameHeaderData( |
3063 SpdyStreamId stream_id, | 3082 SpdyStreamId stream_id, |
3064 const char* data, | 3083 const char* data, |
3065 size_t len) { | 3084 size_t len) { |
3066 // Get a decompressor or set error. | 3085 // Get a decompressor or set error. |
3067 z_stream* decomp = GetHeaderDecompressor(); | 3086 z_stream* decomp = GetHeaderDecompressor(); |
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3234 builder->Seek(compressed_size); | 3253 builder->Seek(compressed_size); |
3235 builder->RewriteLength(*this); | 3254 builder->RewriteLength(*this); |
3236 | 3255 |
3237 pre_compress_bytes.Add(uncompressed_len); | 3256 pre_compress_bytes.Add(uncompressed_len); |
3238 post_compress_bytes.Add(compressed_size); | 3257 post_compress_bytes.Add(compressed_size); |
3239 | 3258 |
3240 compressed_frames.Increment(); | 3259 compressed_frames.Increment(); |
3241 } | 3260 } |
3242 | 3261 |
3243 } // namespace net | 3262 } // namespace net |
OLD | NEW |