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

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

Issue 862133002: Update from https://crrev.com/312398 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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
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 140 matching lines...) Expand 10 before | Expand all | Expand 10 after
151 size_t len) { 151 size_t len) {
152 return true; 152 return true;
153 } 153 }
154 154
155 SpdyFramer::SpdyFramer(SpdyMajorVersion version) 155 SpdyFramer::SpdyFramer(SpdyMajorVersion version)
156 : current_frame_buffer_(new char[kControlFrameBufferSize]), 156 : current_frame_buffer_(new char[kControlFrameBufferSize]),
157 enable_compression_(true), 157 enable_compression_(true),
158 visitor_(NULL), 158 visitor_(NULL),
159 debug_visitor_(NULL), 159 debug_visitor_(NULL),
160 display_protocol_("SPDY"), 160 display_protocol_("SPDY"),
161 spdy_version_(version), 161 protocol_version_(version),
162 syn_frame_processed_(false), 162 syn_frame_processed_(false),
163 probable_http_response_(false), 163 probable_http_response_(false),
164 expect_continuation_(0), 164 expect_continuation_(0),
165 end_stream_when_done_(false) { 165 end_stream_when_done_(false) {
166 DCHECK_GE(spdy_version_, SPDY_MIN_VERSION); 166 DCHECK_GE(protocol_version_, SPDY_MIN_VERSION);
167 DCHECK_LE(spdy_version_, SPDY_MAX_VERSION); 167 DCHECK_LE(protocol_version_, SPDY_MAX_VERSION);
168 DCHECK_LE(kMaxControlFrameSize, 168 DCHECK_LE(kMaxControlFrameSize,
169 SpdyConstants::GetFrameMaximumSize(spdy_version_) + 169 SpdyConstants::GetFrameMaximumSize(protocol_version_) +
170 SpdyConstants::GetControlFrameHeaderSize(spdy_version_)); 170 SpdyConstants::GetControlFrameHeaderSize(protocol_version_));
171 Reset(); 171 Reset();
172 } 172 }
173 173
174 SpdyFramer::~SpdyFramer() { 174 SpdyFramer::~SpdyFramer() {
175 if (header_compressor_.get()) { 175 if (header_compressor_.get()) {
176 deflateEnd(header_compressor_.get()); 176 deflateEnd(header_compressor_.get());
177 } 177 }
178 if (header_decompressor_.get()) { 178 if (header_decompressor_.get()) {
179 inflateEnd(header_decompressor_.get()); 179 inflateEnd(header_decompressor_.get());
180 } 180 }
(...skipping 872 matching lines...) Expand 10 before | Expand all | Expand 10 after
1053 break; 1053 break;
1054 } 1054 }
1055 1055
1056 if (state_ == SPDY_ERROR) { 1056 if (state_ == SPDY_ERROR) {
1057 return; 1057 return;
1058 } 1058 }
1059 1059
1060 if (current_frame_length_ > 1060 if (current_frame_length_ >
1061 SpdyConstants::GetFrameMaximumSize(protocol_version()) + 1061 SpdyConstants::GetFrameMaximumSize(protocol_version()) +
1062 SpdyConstants::GetControlFrameHeaderSize(protocol_version())) { 1062 SpdyConstants::GetControlFrameHeaderSize(protocol_version())) {
1063 DLOG(WARNING) << "Received control frame with way too big of a payload: " 1063 DLOG(WARNING) << "Received control frame of type " << current_frame_type_
1064 << " with way too big of a payload: "
1064 << current_frame_length_; 1065 << current_frame_length_;
1065 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE); 1066 set_error(SPDY_CONTROL_PAYLOAD_TOO_LARGE);
1066 return; 1067 return;
1067 } 1068 }
1068 1069
1069 if (current_frame_type_ == GOAWAY) { 1070 if (current_frame_type_ == GOAWAY) {
1070 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD); 1071 CHANGE_STATE(SPDY_GOAWAY_FRAME_PAYLOAD);
1071 return; 1072 return;
1072 } 1073 }
1073 1074
(...skipping 200 matching lines...) Expand 10 before | Expand all | Expand 10 after
1274 } 1275 }
1275 WriteZ(base::StringPiece(buf, length), clas, out); 1276 WriteZ(base::StringPiece(buf, length), clas, out);
1276 } 1277 }
1277 1278
1278 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a 1279 // WriteHeaderBlockToZ serialises |headers| to the deflate context |z| in a
1279 // manner that resists the length of the compressed data from compromising 1280 // manner that resists the length of the compressed data from compromising
1280 // cookie data. 1281 // cookie data.
1281 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers, 1282 void SpdyFramer::WriteHeaderBlockToZ(const SpdyHeaderBlock* headers,
1282 z_stream* z) const { 1283 z_stream* z) const {
1283 unsigned length_length = 4; 1284 unsigned length_length = 4;
1284 if (spdy_version_ < 3) 1285 if (protocol_version() < 3)
1285 length_length = 2; 1286 length_length = 2;
1286 1287
1287 WriteLengthZ(headers->size(), length_length, kZStandardData, z); 1288 WriteLengthZ(headers->size(), length_length, kZStandardData, z);
1288 1289
1289 std::map<std::string, std::string>::const_iterator it; 1290 std::map<std::string, std::string>::const_iterator it;
1290 for (it = headers->begin(); it != headers->end(); ++it) { 1291 for (it = headers->begin(); it != headers->end(); ++it) {
1291 WriteLengthZ(it->first.size(), length_length, kZStandardData, z); 1292 WriteLengthZ(it->first.size(), length_length, kZStandardData, z);
1292 WriteZ(it->first, kZStandardData, z); 1293 WriteZ(it->first, kZStandardData, z);
1293 1294
1294 if (it->first == "cookie") { 1295 if (it->first == "cookie") {
(...skipping 1674 matching lines...) Expand 10 before | Expand all | Expand 10 after
2969 DCHECK_GT(size, kMaxControlFrameSize); 2970 DCHECK_GT(size, kMaxControlFrameSize);
2970 size_t overflow = size - kMaxControlFrameSize; 2971 size_t overflow = size - kMaxControlFrameSize;
2971 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1; 2972 return overflow / (kMaxControlFrameSize - GetContinuationMinimumSize()) + 1;
2972 } 2973 }
2973 2974
2974 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder, 2975 void SpdyFramer::WritePayloadWithContinuation(SpdyFrameBuilder* builder,
2975 const string& hpack_encoding, 2976 const string& hpack_encoding,
2976 SpdyStreamId stream_id, 2977 SpdyStreamId stream_id,
2977 SpdyFrameType type, 2978 SpdyFrameType type,
2978 int padding_payload_len) { 2979 int padding_payload_len) {
2979 uint8 end_flag = 0; 2980 uint8 end_flag = 0;
2980 uint8 flags = 0; 2981 uint8 flags = 0;
2981 if (type == HEADERS) { 2982 if (type == HEADERS) {
2982 end_flag = HEADERS_FLAG_END_HEADERS; 2983 end_flag = HEADERS_FLAG_END_HEADERS;
2983 } else if (type == PUSH_PROMISE) { 2984 } else if (type == PUSH_PROMISE) {
2984 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE; 2985 end_flag = PUSH_PROMISE_FLAG_END_PUSH_PROMISE;
2985 } else { 2986 } else {
2986 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type " 2987 DLOG(FATAL) << "CONTINUATION frames cannot be used with frame type "
2987 << FrameTypeToString(type); 2988 << FrameTypeToString(type);
2989 }
2990
2991 // Write all the padding payload and as much of the data payload as possible
2992 // into the initial frame.
2993 size_t bytes_remaining = 0;
2994 bytes_remaining =
2995 hpack_encoding.size() -
2996 std::min(hpack_encoding.size(),
2997 kMaxControlFrameSize - builder->length() - padding_payload_len);
2998 builder->WriteBytes(&hpack_encoding[0],
2999 hpack_encoding.size() - bytes_remaining);
3000 if (padding_payload_len > 0) {
3001 string padding = string(padding_payload_len, 0);
3002 builder->WriteBytes(padding.data(), padding.length());
3003 }
3004 if (bytes_remaining > 0) {
3005 builder->OverwriteLength(
3006 *this, kMaxControlFrameSize - GetControlFrameHeaderSize());
3007 }
3008
3009 // Tack on CONTINUATION frames for the overflow.
3010 while (bytes_remaining > 0) {
3011 size_t bytes_to_write = std::min(
3012 bytes_remaining, kMaxControlFrameSize - GetContinuationMinimumSize());
3013 // Write CONTINUATION frame prefix.
3014 if (bytes_remaining == bytes_to_write) {
3015 flags |= end_flag;
2988 } 3016 }
2989 3017 builder->BeginNewFrame(*this, CONTINUATION, flags, stream_id);
2990 // Write all the padding payload and as much of the data payload as possible 3018 // Write payload fragment.
2991 // into the initial frame. 3019 builder->WriteBytes(
2992 size_t bytes_remaining = 0; 3020 &hpack_encoding[hpack_encoding.size() - bytes_remaining],
2993 bytes_remaining = hpack_encoding.size() - 3021 bytes_to_write);
2994 std::min(hpack_encoding.size(), 3022 bytes_remaining -= bytes_to_write;
2995 kMaxControlFrameSize - builder->length() - 3023 }
2996 padding_payload_len);
2997 builder->WriteBytes(&hpack_encoding[0],
2998 hpack_encoding.size() - bytes_remaining);
2999 if (padding_payload_len > 0) {
3000 string padding = string(padding_payload_len, 0);
3001 builder->WriteBytes(padding.data(), padding.length());
3002 }
3003 if (bytes_remaining > 0) {
3004 builder->OverwriteLength(*this,
3005 kMaxControlFrameSize - GetControlFrameHeaderSize());
3006 }
3007
3008 // Tack on CONTINUATION frames for the overflow.
3009 while (bytes_remaining > 0) {
3010 size_t bytes_to_write = std::min(bytes_remaining,
3011 kMaxControlFrameSize -
3012 GetContinuationMinimumSize());
3013 // Write CONTINUATION frame prefix.
3014 if (bytes_remaining == bytes_to_write) {
3015 flags |= end_flag;
3016 }
3017 builder->BeginNewFrame(*this,
3018 CONTINUATION,
3019 flags,
3020 stream_id);
3021 // Write payload fragment.
3022 builder->WriteBytes(&hpack_encoding[hpack_encoding.size() -
3023 bytes_remaining],
3024 bytes_to_write);
3025 bytes_remaining -= bytes_to_write;
3026 }
3027 } 3024 }
3028 3025
3029 // The following compression setting are based on Brian Olson's analysis. See 3026 // The following compression setting are based on Brian Olson's analysis. See
3030 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2 3027 // https://groups.google.com/group/spdy-dev/browse_thread/thread/dfaf498542fac79 2
3031 // for more details. 3028 // for more details.
3032 #if defined(USE_SYSTEM_ZLIB) 3029 #if defined(USE_SYSTEM_ZLIB)
3033 // System zlib is not expected to have workaround for http://crbug.com/139744, 3030 // System zlib is not expected to have workaround for http://crbug.com/139744,
3034 // so disable compression in that case. 3031 // so disable compression in that case.
3035 // TODO(phajdan.jr): Remove the special case when it's no longer necessary. 3032 // TODO(phajdan.jr): Remove the special case when it's no longer necessary.
3036 static const int kCompressorLevel = 0; 3033 static const int kCompressorLevel = 0;
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
3080 int success = inflateInit(header_decompressor_.get()); 3077 int success = inflateInit(header_decompressor_.get());
3081 if (success != Z_OK) { 3078 if (success != Z_OK) {
3082 LOG(WARNING) << "inflateInit failure: " << success; 3079 LOG(WARNING) << "inflateInit failure: " << success;
3083 header_decompressor_.reset(NULL); 3080 header_decompressor_.reset(NULL);
3084 return NULL; 3081 return NULL;
3085 } 3082 }
3086 return header_decompressor_.get(); 3083 return header_decompressor_.get();
3087 } 3084 }
3088 3085
3089 HpackEncoder* SpdyFramer::GetHpackEncoder() { 3086 HpackEncoder* SpdyFramer::GetHpackEncoder() {
3090 DCHECK_LT(SPDY3, spdy_version_); 3087 DCHECK_LT(SPDY3, protocol_version());
3091 if (hpack_encoder_.get() == NULL) { 3088 if (hpack_encoder_.get() == nullptr) {
3092 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable())); 3089 hpack_encoder_.reset(new HpackEncoder(ObtainHpackHuffmanTable()));
3093 } 3090 }
3094 return hpack_encoder_.get(); 3091 return hpack_encoder_.get();
3095 } 3092 }
3096 3093
3097 HpackDecoder* SpdyFramer::GetHpackDecoder() { 3094 HpackDecoder* SpdyFramer::GetHpackDecoder() {
3098 DCHECK_LT(SPDY3, spdy_version_); 3095 DCHECK_LT(SPDY3, protocol_version());
3099 if (hpack_decoder_.get() == NULL) { 3096 if (hpack_decoder_.get() == nullptr) {
3100 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable())); 3097 hpack_decoder_.reset(new HpackDecoder(ObtainHpackHuffmanTable()));
3101 } 3098 }
3102 return hpack_decoder_.get(); 3099 return hpack_decoder_.get();
3103 } 3100 }
3104 3101
3105 uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) { 3102 uint8 SpdyFramer::MapPriorityToWeight(SpdyPriority priority) {
3106 const float kSteps = 255.9f / 7.f; 3103 const float kSteps = 255.9f / 7.f;
3107 return static_cast<uint8>(kSteps * (7.f - priority)); 3104 return static_cast<uint8>(kSteps * (7.f - priority));
3108 } 3105 }
3109 3106
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
3291 builder->Seek(compressed_size); 3288 builder->Seek(compressed_size);
3292 builder->RewriteLength(*this); 3289 builder->RewriteLength(*this);
3293 3290
3294 pre_compress_bytes.Add(uncompressed_len); 3291 pre_compress_bytes.Add(uncompressed_len);
3295 post_compress_bytes.Add(compressed_size); 3292 post_compress_bytes.Add(compressed_size);
3296 3293
3297 compressed_frames.Increment(); 3294 compressed_frames.Increment();
3298 } 3295 }
3299 3296
3300 } // namespace net 3297 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/spdy_framer.h ('k') | net/spdy/spdy_framer_test.cc » ('j') | shell/BUILD.gn » ('J')

Powered by Google App Engine
This is Rietveld 408576698