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

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

Issue 531253004: HPACK: Check pseudo-header order in decoder. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Update examples_07.hpack. Created 6 years, 3 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_decoder.h ('k') | net/spdy/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_decoder.h" 5 #include "net/spdy/hpack_decoder.h"
6 6
7 #include "base/basictypes.h" 7 #include "base/basictypes.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "net/spdy/hpack_constants.h" 9 #include "net/spdy/hpack_constants.h"
10 #include "net/spdy/hpack_output_stream.h" 10 #include "net/spdy/hpack_output_stream.h"
11 11
12 namespace net { 12 namespace net {
13 13
14 using base::StringPiece; 14 using base::StringPiece;
15 using std::string; 15 using std::string;
16 16
17 namespace { 17 namespace {
18 18
19 const char kCookieKey[] = "cookie"; 19 const char kCookieKey[] = "cookie";
20 20
21 } // namespace 21 } // namespace
22 22
23 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table) 23 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table)
24 : max_string_literal_size_(kDefaultMaxStringLiteralSize), 24 : max_string_literal_size_(kDefaultMaxStringLiteralSize),
25 regular_header_seen_(false),
25 huffman_table_(table) {} 26 huffman_table_(table) {}
26 27
27 HpackDecoder::~HpackDecoder() {} 28 HpackDecoder::~HpackDecoder() {}
28 29
29 bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id, 30 bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id,
30 const char* headers_data, 31 const char* headers_data,
31 size_t headers_data_length) { 32 size_t headers_data_length) {
32 decoded_block_.clear(); 33 decoded_block_.clear();
33 34
34 size_t new_size = headers_block_buffer_.size() + headers_data_length; 35 size_t new_size = headers_block_buffer_.size() + headers_data_length;
35 if (new_size > kMaxDecodeBufferSize) { 36 if (new_size > kMaxDecodeBufferSize) {
36 return false; 37 return false;
37 } 38 }
38 headers_block_buffer_.insert(headers_block_buffer_.end(), 39 headers_block_buffer_.insert(headers_block_buffer_.end(),
39 headers_data, 40 headers_data,
40 headers_data + headers_data_length); 41 headers_data + headers_data_length);
41 return true; 42 return true;
42 } 43 }
43 44
44 bool HpackDecoder::HandleControlFrameHeadersComplete(SpdyStreamId id) { 45 bool HpackDecoder::HandleControlFrameHeadersComplete(SpdyStreamId id) {
45 HpackInputStream input_stream(max_string_literal_size_, 46 HpackInputStream input_stream(max_string_literal_size_,
46 headers_block_buffer_); 47 headers_block_buffer_);
48 regular_header_seen_ = false;
47 while (input_stream.HasMoreData()) { 49 while (input_stream.HasMoreData()) {
48 if (!DecodeNextOpcode(&input_stream)) { 50 if (!DecodeNextOpcode(&input_stream)) {
49 headers_block_buffer_.clear(); 51 headers_block_buffer_.clear();
50 return false; 52 return false;
51 } 53 }
52 } 54 }
53 headers_block_buffer_.clear(); 55 headers_block_buffer_.clear();
54 56
55 // Emit the Cookie header, if any crumbles were encountered. 57 // Emit the Cookie header, if any crumbles were encountered.
56 if (!cookie_value_.empty()) { 58 if (!cookie_value_.empty()) {
57 decoded_block_[kCookieKey] = cookie_value_; 59 decoded_block_[kCookieKey] = cookie_value_;
58 cookie_value_.clear(); 60 cookie_value_.clear();
59 } 61 }
60 return true; 62 return true;
61 } 63 }
62 64
63 void HpackDecoder::HandleHeaderRepresentation(StringPiece name, 65 bool HpackDecoder::HandleHeaderRepresentation(StringPiece name,
64 StringPiece value) { 66 StringPiece value) {
65 typedef std::pair<std::map<string, string>::iterator, bool> InsertResult; 67 typedef std::pair<std::map<string, string>::iterator, bool> InsertResult;
66 68
69 // Fail if pseudo-header follows regular header.
70 if (name.size() > 0) {
71 if (name[0] == kPseudoHeaderPrefix) {
72 if (regular_header_seen_) return false;
73 } else {
74 regular_header_seen_ = true;
75 }
76 }
77
67 if (name == kCookieKey) { 78 if (name == kCookieKey) {
68 if (cookie_value_.empty()) { 79 if (cookie_value_.empty()) {
69 cookie_value_.assign(value.data(), value.size()); 80 cookie_value_.assign(value.data(), value.size());
70 } else { 81 } else {
71 cookie_value_ += "; "; 82 cookie_value_ += "; ";
72 cookie_value_.insert(cookie_value_.end(), value.begin(), value.end()); 83 cookie_value_.insert(cookie_value_.end(), value.begin(), value.end());
73 } 84 }
74 } else { 85 } else {
75 InsertResult result = decoded_block_.insert( 86 InsertResult result = decoded_block_.insert(
76 std::make_pair(name.as_string(), value.as_string())); 87 std::make_pair(name.as_string(), value.as_string()));
77 if (!result.second) { 88 if (!result.second) {
78 result.first->second.push_back('\0'); 89 result.first->second.push_back('\0');
79 result.first->second.insert(result.first->second.end(), 90 result.first->second.insert(result.first->second.end(),
80 value.begin(), 91 value.begin(),
81 value.end()); 92 value.end());
82 } 93 }
83 } 94 }
95 return true;
84 } 96 }
85 97
86 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) { 98 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) {
87 // Implements 7.1: Indexed Header Field Representation. 99 // Implements 7.1: Indexed Header Field Representation.
88 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) { 100 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) {
89 return DecodeNextIndexedHeader(input_stream); 101 return DecodeNextIndexedHeader(input_stream);
90 } 102 }
91 // Implements 7.2.1: Literal Header Field with Incremental Indexing. 103 // Implements 7.2.1: Literal Header Field with Incremental Indexing.
92 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { 104 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) {
93 return DecodeNextLiteralHeader(input_stream, true); 105 return DecodeNextLiteralHeader(input_stream, true);
(...skipping 30 matching lines...) Expand all
124 136
125 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) { 137 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) {
126 uint32 index = 0; 138 uint32 index = 0;
127 if (!input_stream->DecodeNextUint32(&index)) 139 if (!input_stream->DecodeNextUint32(&index))
128 return false; 140 return false;
129 141
130 HpackEntry* entry = header_table_.GetByIndex(index); 142 HpackEntry* entry = header_table_.GetByIndex(index);
131 if (entry == NULL) 143 if (entry == NULL)
132 return false; 144 return false;
133 145
134 HandleHeaderRepresentation(entry->name(), entry->value()); 146 return HandleHeaderRepresentation(entry->name(), entry->value());
135 return true;
136 } 147 }
137 148
138 bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream, 149 bool HpackDecoder::DecodeNextLiteralHeader(HpackInputStream* input_stream,
139 bool should_index) { 150 bool should_index) {
140 StringPiece name; 151 StringPiece name;
141 if (!DecodeNextName(input_stream, &name)) 152 if (!DecodeNextName(input_stream, &name))
142 return false; 153 return false;
143 154
144 StringPiece value; 155 StringPiece value;
145 if (!DecodeNextStringLiteral(input_stream, false, &value)) 156 if (!DecodeNextStringLiteral(input_stream, false, &value))
146 return false; 157 return false;
147 158
148 HandleHeaderRepresentation(name, value); 159 if (!HandleHeaderRepresentation(name, value)) return false;
149 160
150 if (!should_index) 161 if (!should_index)
151 return true; 162 return true;
152 163
153 ignore_result(header_table_.TryAddEntry(name, value)); 164 ignore_result(header_table_.TryAddEntry(name, value));
154 return true; 165 return true;
155 } 166 }
156 167
157 bool HpackDecoder::DecodeNextName( 168 bool HpackDecoder::DecodeNextName(
158 HpackInputStream* input_stream, StringPiece* next_name) { 169 HpackInputStream* input_stream, StringPiece* next_name) {
(...skipping 27 matching lines...) Expand all
186 return result; 197 return result;
187 } else if (input_stream->MatchPrefixAndConsume( 198 } else if (input_stream->MatchPrefixAndConsume(
188 kStringLiteralIdentityEncoded)) { 199 kStringLiteralIdentityEncoded)) {
189 return input_stream->DecodeNextIdentityString(output); 200 return input_stream->DecodeNextIdentityString(output);
190 } else { 201 } else {
191 return false; 202 return false;
192 } 203 }
193 } 204 }
194 205
195 } // namespace net 206 } // namespace net
OLDNEW
« no previous file with comments | « net/spdy/hpack_decoder.h ('k') | net/spdy/hpack_decoder_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698