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

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

Issue 448433002: Update HPACK implementation to draft-09 (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Generate examples_07.hpack. Created 6 years, 4 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 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_decoder.h" 5 #include "net/spdy/hpack_decoder.h"
6 6
7 #include <utility>
Johnny 2014/08/06 15:04:49 I don't see a use of this below?
Bence 2014/08/06 20:20:22 It's for std::pair. git cl lint complains if this
Johnny 2014/08/07 17:02:22 Oh, great. SGTM then.
Bence 2014/08/08 13:57:55 Acknowledged.
8
7 #include "base/basictypes.h" 9 #include "base/basictypes.h"
8 #include "base/logging.h" 10 #include "base/logging.h"
9 #include "net/spdy/hpack_constants.h" 11 #include "net/spdy/hpack_constants.h"
10 #include "net/spdy/hpack_output_stream.h" 12 #include "net/spdy/hpack_output_stream.h"
11 13
12 namespace net { 14 namespace net {
13 15
14 using base::StringPiece; 16 using base::StringPiece;
15 using std::string; 17 using std::string;
16 18
17 namespace { 19 namespace {
18 20
19 const uint8 kNoState = 0;
20 // Set on entries added to the reference set during this decoding.
21 const uint8 kReferencedThisEncoding = 1;
22
23 const char kCookieKey[] = "cookie"; 21 const char kCookieKey[] = "cookie";
24 22
25 } // namespace 23 } // namespace
26 24
27 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table) 25 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table)
28 : max_string_literal_size_(kDefaultMaxStringLiteralSize), 26 : max_string_literal_size_(kDefaultMaxStringLiteralSize),
29 huffman_table_(table) {} 27 huffman_table_(table) {}
30 28
31 HpackDecoder::~HpackDecoder() {} 29 HpackDecoder::~HpackDecoder() {}
32 30
(...skipping 16 matching lines...) Expand all
49 HpackInputStream input_stream(max_string_literal_size_, 47 HpackInputStream input_stream(max_string_literal_size_,
50 headers_block_buffer_); 48 headers_block_buffer_);
51 while (input_stream.HasMoreData()) { 49 while (input_stream.HasMoreData()) {
52 if (!DecodeNextOpcode(&input_stream)) { 50 if (!DecodeNextOpcode(&input_stream)) {
53 headers_block_buffer_.clear(); 51 headers_block_buffer_.clear();
54 return false; 52 return false;
55 } 53 }
56 } 54 }
57 headers_block_buffer_.clear(); 55 headers_block_buffer_.clear();
58 56
59 // Emit everything in the reference set that hasn't already been emitted.
60 // Also clear entry state for the next decoded headers block.
61 // TODO(jgraettinger): We may need to revisit the order in which headers
62 // are emitted (b/14051713).
63 for (HpackHeaderTable::OrderedEntrySet::const_iterator it =
64 header_table_.reference_set().begin();
65 it != header_table_.reference_set().end(); ++it) {
66 HpackEntry* entry = *it;
67
68 if (entry->state() == kNoState) {
69 HandleHeaderRepresentation(entry->name(), entry->value());
70 } else {
71 entry->set_state(kNoState);
72 }
73 }
74 // Emit the Cookie header, if any crumbles were encountered. 57 // Emit the Cookie header, if any crumbles were encountered.
75 if (!cookie_value_.empty()) { 58 if (!cookie_value_.empty()) {
76 decoded_block_[kCookieKey] = cookie_value_; 59 decoded_block_[kCookieKey] = cookie_value_;
77 cookie_value_.clear(); 60 cookie_value_.clear();
78 } 61 }
79 return true; 62 return true;
80 } 63 }
81 64
82 void HpackDecoder::HandleHeaderRepresentation(StringPiece name, 65 void HpackDecoder::HandleHeaderRepresentation(StringPiece name,
83 StringPiece value) { 66 StringPiece value) {
(...skipping 30 matching lines...) Expand all
114 // Implements 4.3.2: Literal Header Field with Incremental Indexing. 97 // Implements 4.3.2: Literal Header Field with Incremental Indexing.
115 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { 98 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) {
116 return DecodeNextLiteralHeader(input_stream, true); 99 return DecodeNextLiteralHeader(input_stream, true);
117 } 100 }
118 // Implements 4.3.3: Literal Header Field never Indexed. 101 // Implements 4.3.3: Literal Header Field never Indexed.
119 // TODO(jgraettinger): Preserve the never-indexed bit. 102 // TODO(jgraettinger): Preserve the never-indexed bit.
120 if (input_stream->MatchPrefixAndConsume(kLiteralNeverIndexOpcode)) { 103 if (input_stream->MatchPrefixAndConsume(kLiteralNeverIndexOpcode)) {
121 return DecodeNextLiteralHeader(input_stream, false); 104 return DecodeNextLiteralHeader(input_stream, false);
122 } 105 }
123 // Implements 4.4: Encoding context update. 106 // Implements 4.4: Encoding context update.
124 if (input_stream->MatchPrefixAndConsume(kEncodingContextOpcode)) { 107 if (input_stream->MatchPrefixAndConsume(kHeaderTableSizeUpdateOpcode)) {
125 return DecodeNextContextUpdate(input_stream); 108 return DecodeNextHeaderTableSizeUpdate(input_stream);
126 } 109 }
127 // Unrecognized opcode. 110 // Unrecognized opcode.
128 return false; 111 return false;
129 } 112 }
130 113
131 bool HpackDecoder::DecodeNextContextUpdate(HpackInputStream* input_stream) { 114 bool HpackDecoder::DecodeNextHeaderTableSizeUpdate(
132 if (input_stream->MatchPrefixAndConsume(kEncodingContextEmptyReferenceSet)) { 115 HpackInputStream* input_stream) {
133 header_table_.ClearReferenceSet(); 116 uint32 size = 0;
134 return true; 117 if (!input_stream->DecodeNextUint32(&size)) {
118 return false;
135 } 119 }
136 if (input_stream->MatchPrefixAndConsume(kEncodingContextNewMaximumSize)) { 120 if (size > header_table_.settings_size_bound()) {
137 uint32 size = 0; 121 return false;
138 if (!input_stream->DecodeNextUint32(&size)) {
139 return false;
140 }
141 if (size > header_table_.settings_size_bound()) {
142 return false;
143 }
144 header_table_.SetMaxSize(size);
145 return true;
146 } 122 }
147 // Unrecognized encoding context update. 123 header_table_.SetMaxSize(size);
148 return false; 124 return true;
149 } 125 }
150 126
151 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) { 127 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) {
152 uint32 index = 0; 128 uint32 index = 0;
153 if (!input_stream->DecodeNextUint32(&index)) 129 if (!input_stream->DecodeNextUint32(&index))
154 return false; 130 return false;
155 131
156 HpackEntry* entry = header_table_.GetByIndex(index); 132 HpackEntry* entry = header_table_.GetByIndex(index);
157 if (entry == NULL) 133 if (entry == NULL)
158 return false; 134 return false;
159 135
160 if (entry->IsStatic()) { 136 HandleHeaderRepresentation(entry->name(), entry->value());
161 HandleHeaderRepresentation(entry->name(), entry->value());
162
163 HpackEntry* new_entry = header_table_.TryAddEntry(
164 entry->name(), entry->value());
165 if (new_entry) {
166 header_table_.Toggle(new_entry);
167 new_entry->set_state(kReferencedThisEncoding);
168 }
169 } else {
170 entry->set_state(kNoState);
171 if (header_table_.Toggle(entry)) {
172 HandleHeaderRepresentation(entry->name(), entry->value());
173 entry->set_state(kReferencedThisEncoding);
174 }
175 }
176 return true; 137 return true;
177 } 138 }
178 139
179 bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream, 140 bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream,
180 bool should_index) { 141 bool should_index) {
181 StringPiece name; 142 StringPiece name;
182 if (!DecodeNextName(input_stream, &name)) 143 if (!DecodeNextName(input_stream, &name))
183 return false; 144 return false;
184 145
185 StringPiece value; 146 StringPiece value;
186 if (!DecodeNextStringLiteral(input_stream, false, &value)) 147 if (!DecodeNextStringLiteral(input_stream, false, &value))
187 return false; 148 return false;
188 149
189 HandleHeaderRepresentation(name, value); 150 HandleHeaderRepresentation(name, value);
190 151
191 if (!should_index) 152 if (!should_index)
192 return true; 153 return true;
193 154
194 HpackEntry* new_entry = header_table_.TryAddEntry(name, value); 155 header_table_.TryAddEntry(name, value);
Johnny 2014/08/06 15:04:49 ignore_result
Bence 2014/08/06 20:20:22 Done.
195 if (new_entry) {
196 header_table_.Toggle(new_entry);
197 new_entry->set_state(kReferencedThisEncoding);
198 }
199 return true; 156 return true;
200 } 157 }
201 158
202 bool HpackDecoder::DecodeNextName( 159 bool HpackDecoder::DecodeNextName(
203 HpackInputStream* input_stream, StringPiece* next_name) { 160 HpackInputStream* input_stream, StringPiece* next_name) {
204 uint32 index_or_zero = 0; 161 uint32 index_or_zero = 0;
205 if (!input_stream->DecodeNextUint32(&index_or_zero)) 162 if (!input_stream->DecodeNextUint32(&index_or_zero))
206 return false; 163 return false;
207 164
208 if (index_or_zero == 0) 165 if (index_or_zero == 0)
(...skipping 22 matching lines...) Expand all
231 return result; 188 return result;
232 } else if (input_stream->MatchPrefixAndConsume( 189 } else if (input_stream->MatchPrefixAndConsume(
233 kStringLiteralIdentityEncoded)) { 190 kStringLiteralIdentityEncoded)) {
234 return input_stream->DecodeNextIdentityString(output); 191 return input_stream->DecodeNextIdentityString(output);
235 } else { 192 } else {
236 return false; 193 return false;
237 } 194 }
238 } 195 }
239 196
240 } // namespace net 197 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698