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

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

Issue 265763011: Land recent SPDY changes (through 66310528) (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 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 | Annotate | Revision Log
« 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 "base/strings/string_util.h"
10 #include "net/spdy/hpack_constants.h" 9 #include "net/spdy/hpack_constants.h"
11 #include "net/spdy/hpack_output_stream.h" 10 #include "net/spdy/hpack_output_stream.h"
12 11
13 namespace net { 12 namespace net {
14 13
15 using base::StringPiece; 14 using base::StringPiece;
16 using std::string; 15 using std::string;
17 16
18 namespace { 17 namespace {
19 18
20 const uint8 kNoState = 0; 19 const uint8 kNoState = 0;
21 // Set on entries added to the reference set during this decoding. 20 // Set on entries added to the reference set during this decoding.
22 const uint8 kReferencedThisEncoding = 1; 21 const uint8 kReferencedThisEncoding = 1;
23 22
23 const char kCookieKey[] = "cookie";
24
24 } // namespace 25 } // namespace
25 26
26 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table) 27 HpackDecoder::HpackDecoder(const HpackHuffmanTable& table)
27 : max_string_literal_size_(kDefaultMaxStringLiteralSize), 28 : max_string_literal_size_(kDefaultMaxStringLiteralSize),
28 huffman_table_(table) {} 29 huffman_table_(table) {}
29 30
30 HpackDecoder::~HpackDecoder() {} 31 HpackDecoder::~HpackDecoder() {}
31 32
32 bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id, 33 bool HpackDecoder::HandleControlFrameHeadersData(SpdyStreamId id,
33 const char* headers_data, 34 const char* headers_data,
(...skipping 28 matching lines...) Expand all
62 it != header_table_.reference_set().end(); ++it) { 63 it != header_table_.reference_set().end(); ++it) {
63 HpackEntry* entry = *it; 64 HpackEntry* entry = *it;
64 65
65 if (entry->state() == kNoState) { 66 if (entry->state() == kNoState) {
66 HandleHeaderRepresentation(entry->name(), entry->value()); 67 HandleHeaderRepresentation(entry->name(), entry->value());
67 } else { 68 } else {
68 entry->set_state(kNoState); 69 entry->set_state(kNoState);
69 } 70 }
70 } 71 }
71 // Emit the Cookie header, if any crumbles were encountered. 72 // Emit the Cookie header, if any crumbles were encountered.
72 if (!cookie_name_.empty()) { 73 if (!cookie_value_.empty()) {
73 decoded_block_[cookie_name_] = cookie_value_; 74 decoded_block_[kCookieKey] = cookie_value_;
74 cookie_name_.clear();
75 cookie_value_.clear(); 75 cookie_value_.clear();
76 } 76 }
77 return true; 77 return true;
78 } 78 }
79 79
80 void HpackDecoder::HandleHeaderRepresentation(StringPiece name, 80 void HpackDecoder::HandleHeaderRepresentation(StringPiece name,
81 StringPiece value) { 81 StringPiece value) {
82 typedef std::pair<std::map<string, string>::iterator, bool> InsertResult; 82 typedef std::pair<std::map<string, string>::iterator, bool> InsertResult;
83 83
84 // TODO(jgraettinger): HTTP/2 requires strict lowercasing of headers, 84 if (name == kCookieKey) {
85 // and the permissiveness here isn't wanted. Back this out in upstream. 85 if (cookie_value_.empty()) {
86 if (LowerCaseEqualsASCII(name.begin(), name.end(), "cookie")) {
87 if (cookie_name_.empty()) {
88 cookie_name_.assign(name.data(), name.size());
89 cookie_value_.assign(value.data(), value.size()); 86 cookie_value_.assign(value.data(), value.size());
90 } else { 87 } else {
91 cookie_value_ += "; "; 88 cookie_value_ += "; ";
92 cookie_value_.insert(cookie_value_.end(), value.begin(), value.end()); 89 cookie_value_.insert(cookie_value_.end(), value.begin(), value.end());
93 } 90 }
94 } else { 91 } else {
95 InsertResult result = decoded_block_.insert( 92 InsertResult result = decoded_block_.insert(
96 std::make_pair(name.as_string(), value.as_string())); 93 std::make_pair(name.as_string(), value.as_string()));
97 if (!result.second) { 94 if (!result.second) {
98 result.first->second.push_back('\0'); 95 result.first->second.push_back('\0');
99 result.first->second.insert(result.first->second.end(), 96 result.first->second.insert(result.first->second.end(),
100 value.begin(), 97 value.begin(),
101 value.end()); 98 value.end());
102 } 99 }
103 } 100 }
104 } 101 }
105 102
106 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) { 103 bool HpackDecoder::DecodeNextOpcode(HpackInputStream* input_stream) {
107 // Implements 4.4: Encoding context update. Context updates are a special-case
108 // of indexed header, and must be tested prior to |kIndexedOpcode| below.
109 if (input_stream->MatchPrefixAndConsume(kEncodingContextOpcode)) {
110 return DecodeNextContextUpdate(input_stream);
111 }
112 // Implements 4.2: Indexed Header Field Representation. 104 // Implements 4.2: Indexed Header Field Representation.
113 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) { 105 if (input_stream->MatchPrefixAndConsume(kIndexedOpcode)) {
114 return DecodeNextIndexedHeader(input_stream); 106 return DecodeNextIndexedHeader(input_stream);
115 } 107 }
116 // Implements 4.3.1: Literal Header Field without Indexing. 108 // Implements 4.3.1: Literal Header Field without Indexing.
117 if (input_stream->MatchPrefixAndConsume(kLiteralNoIndexOpcode)) { 109 if (input_stream->MatchPrefixAndConsume(kLiteralNoIndexOpcode)) {
118 return DecodeNextLiteralHeader(input_stream, false); 110 return DecodeNextLiteralHeader(input_stream, false);
119 } 111 }
120 // Implements 4.3.2: Literal Header Field with Incremental Indexing. 112 // Implements 4.3.2: Literal Header Field with Incremental Indexing.
121 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) { 113 if (input_stream->MatchPrefixAndConsume(kLiteralIncrementalIndexOpcode)) {
122 return DecodeNextLiteralHeader(input_stream, true); 114 return DecodeNextLiteralHeader(input_stream, true);
123 } 115 }
116 // Implements 4.3.3: Literal Header Field never Indexed.
117 // TODO(jgraettinger): Preserve the never-indexed bit.
118 if (input_stream->MatchPrefixAndConsume(kLiteralNeverIndexOpcode)) {
119 return DecodeNextLiteralHeader(input_stream, false);
120 }
121 // Implements 4.4: Encoding context update.
122 if (input_stream->MatchPrefixAndConsume(kEncodingContextOpcode)) {
123 return DecodeNextContextUpdate(input_stream);
124 }
124 // Unrecognized opcode. 125 // Unrecognized opcode.
125 return false; 126 return false;
126 } 127 }
127 128
128 bool HpackDecoder::DecodeNextContextUpdate(HpackInputStream* input_stream) { 129 bool HpackDecoder::DecodeNextContextUpdate(HpackInputStream* input_stream) {
129 if (input_stream->MatchPrefixAndConsume(kEncodingContextEmptyReferenceSet)) { 130 if (input_stream->MatchPrefixAndConsume(kEncodingContextEmptyReferenceSet)) {
130 header_table_.ClearReferenceSet(); 131 header_table_.ClearReferenceSet();
131 return true; 132 return true;
132 } 133 }
133 if (input_stream->MatchPrefixAndConsume(kEncodingContextNewMaximumSize)) { 134 if (input_stream->MatchPrefixAndConsume(kEncodingContextNewMaximumSize)) {
134 uint32 size = 0; 135 uint32 size = 0;
135 if (!input_stream->DecodeNextUint32(&size)) { 136 if (!input_stream->DecodeNextUint32(&size)) {
136 return false; 137 return false;
137 } 138 }
138 if (size > header_table_.settings_size_bound()) { 139 if (size > header_table_.settings_size_bound()) {
139 return false; 140 return false;
140 } 141 }
141 header_table_.SetMaxSize(size); 142 header_table_.SetMaxSize(size);
142 return true; 143 return true;
143 } 144 }
144 // Unrecognized encoding context update. 145 // Unrecognized encoding context update.
145 return false; 146 return false;
146 } 147 }
147 148
148 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) { 149 bool HpackDecoder::DecodeNextIndexedHeader(HpackInputStream* input_stream) {
149 uint32 index = 0; 150 uint32 index = 0;
150 if (!input_stream->DecodeNextUint32(&index)) 151 if (!input_stream->DecodeNextUint32(&index))
151 return false; 152 return false;
152 153
153 // If index == 0, |kEncodingContextOpcode| would have matched.
154 CHECK_NE(index, 0u);
155
156 HpackEntry* entry = header_table_.GetByIndex(index); 154 HpackEntry* entry = header_table_.GetByIndex(index);
157 if (entry == NULL) 155 if (entry == NULL)
158 return false; 156 return false;
159 157
160 if (entry->IsStatic()) { 158 if (entry->IsStatic()) {
161 HandleHeaderRepresentation(entry->name(), entry->value()); 159 HandleHeaderRepresentation(entry->name(), entry->value());
162 160
163 HpackEntry* new_entry = header_table_.TryAddEntry( 161 HpackEntry* new_entry = header_table_.TryAddEntry(
164 entry->name(), entry->value()); 162 entry->name(), entry->value());
165 if (new_entry) { 163 if (new_entry) {
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
231 return result; 229 return result;
232 } else if (input_stream->MatchPrefixAndConsume( 230 } else if (input_stream->MatchPrefixAndConsume(
233 kStringLiteralIdentityEncoded)) { 231 kStringLiteralIdentityEncoded)) {
234 return input_stream->DecodeNextIdentityString(output); 232 return input_stream->DecodeNextIdentityString(output);
235 } else { 233 } else {
236 return false; 234 return false;
237 } 235 }
238 } 236 }
239 237
240 } // namespace net 238 } // 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