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

Side by Side Diff: net/spdy/hpack/hpack_decoder.cc

Issue 1914193002: Implements incremental decode in HPACK. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 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/hpack/hpack_decoder.h ('k') | net/spdy/hpack/hpack_decoder_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 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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/hpack/hpack_decoder.h" 5 #include "net/spdy/hpack/hpack_decoder.h"
6 6
7 #include <utility> 7 #include <utility>
8 8
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "net/spdy/hpack/hpack_constants.h" 10 #include "net/spdy/hpack/hpack_constants.h"
11 #include "net/spdy/hpack/hpack_output_stream.h" 11 #include "net/spdy/hpack/hpack_output_stream.h"
12 12
13 namespace net { 13 namespace net {
14 14
15 using base::StringPiece; 15 using base::StringPiece;
16 using std::string; 16 using std::string;
17 17
18 namespace { 18 namespace {
19 19
20 const char kCookieKey[] = "cookie"; 20 const char kCookieKey[] = "cookie";
21 21
22 } // namespace 22 } // namespace
23 23
24 HpackDecoder::HpackDecoder() 24 HpackDecoder::HpackDecoder()
25 : max_string_literal_size_(kDefaultMaxStringLiteralSize), 25 : max_string_literal_size_(kDefaultMaxStringLiteralSize),
26 handler_(nullptr), 26 handler_(nullptr),
27 total_header_bytes_(0), 27 total_header_bytes_(0),
28 regular_header_seen_(false), 28 regular_header_seen_(false),
29 header_block_started_(false) {} 29 header_block_started_(false),
30 total_parsed_bytes_(0) {}
30 31
31 HpackDecoder::~HpackDecoder() {} 32 HpackDecoder::~HpackDecoder() {}
32 33
33 bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data, 34 bool HpackDecoder::HandleControlFrameHeadersData(const char* headers_data,
34 size_t headers_data_length) { 35 size_t headers_data_length) {
35 decoded_block_.clear();
36 if (!header_block_started_) { 36 if (!header_block_started_) {
37 header_block_started_ = true; 37 header_block_started_ = true;
38 decoded_block_.clear();
38 if (handler_ != nullptr) { 39 if (handler_ != nullptr) {
39 handler_->OnHeaderBlockStart(); 40 handler_->OnHeaderBlockStart();
40 } 41 }
41 } 42 }
42 size_t new_size = headers_block_buffer_.size() + headers_data_length; 43 size_t new_size = headers_block_buffer_.size() + headers_data_length;
43 if (new_size > kMaxDecodeBufferSize) { 44 if (new_size > kMaxDecodeBufferSize) {
44 return false; 45 return false;
45 } 46 }
46 headers_block_buffer_.insert(headers_block_buffer_.end(), headers_data, 47 headers_block_buffer_.insert(headers_block_buffer_.end(), headers_data,
47 headers_data + headers_data_length); 48 headers_data + headers_data_length);
49
50 // Parse as many data in buffer as possible. And remove the parsed data
51 // from buffer.
52 HpackInputStream input_stream(max_string_literal_size_,
53 headers_block_buffer_);
54 while (input_stream.HasMoreData()) {
55 if (!DecodeNextOpcodeWrapper(&input_stream)) {
56 if (input_stream.NeedMoreData()) {
57 break;
58 }
59 return false;
60 }
61 }
62 uint32_t parsed_bytes = input_stream.ParsedBytes();
63 DCHECK_GE(headers_block_buffer_.size(), parsed_bytes);
64 headers_block_buffer_.erase(0, parsed_bytes);
65 total_parsed_bytes_ += parsed_bytes;
48 return true; 66 return true;
49 } 67 }
50 68
51 bool HpackDecoder::HandleControlFrameHeadersComplete(size_t* compressed_len) { 69 bool HpackDecoder::HandleControlFrameHeadersComplete(size_t* compressed_len) {
52 HpackInputStream input_stream(max_string_literal_size_,
53 headers_block_buffer_);
54 regular_header_seen_ = false; 70 regular_header_seen_ = false;
55 if (compressed_len) { 71
56 *compressed_len = headers_block_buffer_.size(); 72 if (compressed_len != nullptr) {
73 *compressed_len = total_parsed_bytes_;
57 } 74 }
58 while (input_stream.HasMoreData()) { 75
59 if (!DecodeNextOpcode(&input_stream)) { 76 // Data in headers_block_buffer_ should have been parsed by
60 headers_block_buffer_.clear(); 77 // HandleControlFrameHeadersData and removed.
61 return false; 78 if (headers_block_buffer_.size() > 0) {
62 } 79 return false;
63 } 80 }
81
64 if (handler_ != nullptr) { 82 if (handler_ != nullptr) {
65 handler_->OnHeaderBlockEnd(total_header_bytes_); 83 handler_->OnHeaderBlockEnd(total_header_bytes_);
66 } 84 }
67 headers_block_buffer_.clear(); 85 headers_block_buffer_.clear();
86 total_parsed_bytes_ = 0;
68 header_block_started_ = false; 87 header_block_started_ = false;
69 handler_ = nullptr; 88 handler_ = nullptr;
70 return true; 89 return true;
71 } 90 }
72 91
73 bool HpackDecoder::HandleHeaderRepresentation(StringPiece name, 92 bool HpackDecoder::HandleHeaderRepresentation(StringPiece name,
74 StringPiece value) { 93 StringPiece value) {
75 total_header_bytes_ += name.size() + value.size(); 94 total_header_bytes_ += name.size() + value.size();
76 95
77 // Fail if pseudo-header follows regular header. 96 // Fail if pseudo-header follows regular header.
(...skipping 19 matching lines...) Expand all
97 value.AppendToString(&new_value); 116 value.AppendToString(&new_value);
98 decoded_block_.ReplaceOrAppendHeader(name, new_value); 117 decoded_block_.ReplaceOrAppendHeader(name, new_value);
99 } 118 }
100 } else { 119 } else {
101 DCHECK(decoded_block_.empty()); 120 DCHECK(decoded_block_.empty());
102 handler_->OnHeader(name, value); 121 handler_->OnHeader(name, value);
103 } 122 }
104 return true; 123 return true;
105 } 124 }
106 125
126 bool HpackDecoder::DecodeNextOpcodeWrapper(HpackInputStream* input_stream) {
127 if (DecodeNextOpcode(input_stream)) {
128 // Decoding next opcode succeeds. Mark total bytes parsed successfully.
129 input_stream->MarkCurrentPosition();
130 return true;
131 }
132 return false;
133 }
134
107 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) { 135 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) {
108 // Implements 7.1: Indexed Header Field Representation. 136 // Implements 7.1: Indexed Header Field Representation.
109 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) { 137 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) {
110 return DecodeNextIndexedHeader(input_stream); 138 return DecodeNextIndexedHeader(input_stream);
111 } 139 }
112 // Implements 7.2.1: Literal Header Field with Incremental Indexing. 140 // Implements 7.2.1: Literal Header Field with Incremental Indexing.
113 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { 141 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) {
114 return DecodeNextLiteralHeader(input_stream, true); 142 return DecodeNextLiteralHeader(input_stream, true);
115 } 143 }
116 // Implements 7.2.2: Literal Header Field without Indexing. 144 // Implements 7.2.2: Literal Header Field without Indexing.
(...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after
215 *output = StringPiece(*buffer); 243 *output = StringPiece(*buffer);
216 return result; 244 return result;
217 } 245 }
218 if (input_stream->MatchPrefixAndConsume(kStringLiteralIdentityEncoded)) { 246 if (input_stream->MatchPrefixAndConsume(kStringLiteralIdentityEncoded)) {
219 return input_stream->DecodeNextIdentityString(output); 247 return input_stream->DecodeNextIdentityString(output);
220 } 248 }
221 return false; 249 return false;
222 } 250 }
223 251
224 } // namespace net 252 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack/hpack_decoder.h ('k') | net/spdy/hpack/hpack_decoder_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698