Chromium Code Reviews| 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 |