OLD | NEW |
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_encoder.h" | 5 #include "net/spdy/hpack/hpack_encoder.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 #include <limits> | 8 #include <limits> |
9 | 9 |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
49 | 49 |
50 private: | 50 private: |
51 Representations::const_iterator pseudo_begin_; | 51 Representations::const_iterator pseudo_begin_; |
52 Representations::const_iterator pseudo_end_; | 52 Representations::const_iterator pseudo_end_; |
53 Representations::const_iterator regular_begin_; | 53 Representations::const_iterator regular_begin_; |
54 Representations::const_iterator regular_end_; | 54 Representations::const_iterator regular_end_; |
55 }; | 55 }; |
56 | 56 |
57 namespace { | 57 namespace { |
58 | 58 |
| 59 // The default header listener. |
| 60 void NoOpListener(StringPiece /*name*/, StringPiece /*value*/) {} |
| 61 |
59 // The default HPACK indexing policy. | 62 // The default HPACK indexing policy. |
60 bool DefaultPolicy(StringPiece name, StringPiece /* value */) { | 63 bool DefaultPolicy(StringPiece name, StringPiece /* value */) { |
61 if (name.empty()) { | 64 if (name.empty()) { |
62 return false; | 65 return false; |
63 } | 66 } |
64 // :authority is always present and rarely changes, and has moderate | 67 // :authority is always present and rarely changes, and has moderate |
65 // length, therefore it makes a lot of sense to index (insert in the | 68 // length, therefore it makes a lot of sense to index (insert in the |
66 // dynamic table). | 69 // dynamic table). |
67 if (name[0] == kPseudoHeaderPrefix) { | 70 if (name[0] == kPseudoHeaderPrefix) { |
68 return name == ":authority"; | 71 return name == ":authority"; |
69 } | 72 } |
70 return true; | 73 return true; |
71 } | 74 } |
72 | 75 |
73 } // namespace | 76 } // namespace |
74 | 77 |
75 HpackEncoder::HpackEncoder(const HpackHuffmanTable& table) | 78 HpackEncoder::HpackEncoder(const HpackHuffmanTable& table) |
76 : output_stream_(), | 79 : output_stream_(), |
77 huffman_table_(table), | 80 huffman_table_(table), |
78 min_table_size_setting_received_(std::numeric_limits<size_t>::max()), | 81 min_table_size_setting_received_(std::numeric_limits<size_t>::max()), |
| 82 listener_(NoOpListener), |
79 should_index_(DefaultPolicy), | 83 should_index_(DefaultPolicy), |
80 allow_huffman_compression_(true), | 84 allow_huffman_compression_(true), |
81 should_emit_table_size_(false) {} | 85 should_emit_table_size_(false) {} |
82 | 86 |
83 HpackEncoder::~HpackEncoder() {} | 87 HpackEncoder::~HpackEncoder() {} |
84 | 88 |
85 void HpackEncoder::EncodeHeaderSet(const Representations& representations, | 89 void HpackEncoder::EncodeHeaderSet(const Representations& representations, |
86 string* output) { | 90 string* output) { |
87 RepresentationIterator iter(representations); | 91 RepresentationIterator iter(representations); |
88 EncodeRepresentations(&iter, output); | 92 EncodeRepresentations(&iter, output); |
(...skipping 25 matching lines...) Expand all Loading... |
114 } | 118 } |
115 return true; | 119 return true; |
116 } | 120 } |
117 | 121 |
118 bool HpackEncoder::EncodeHeaderSetWithoutCompression( | 122 bool HpackEncoder::EncodeHeaderSetWithoutCompression( |
119 const SpdyHeaderBlock& header_set, | 123 const SpdyHeaderBlock& header_set, |
120 string* output) { | 124 string* output) { |
121 allow_huffman_compression_ = false; | 125 allow_huffman_compression_ = false; |
122 MaybeEmitTableSize(); | 126 MaybeEmitTableSize(); |
123 for (const auto& header : header_set) { | 127 for (const auto& header : header_set) { |
| 128 listener_(header.first, header.second); |
124 // Note that cookies are not crumbled in this case. | 129 // Note that cookies are not crumbled in this case. |
125 EmitNonIndexedLiteral(header); | 130 EmitNonIndexedLiteral(header); |
126 } | 131 } |
127 allow_huffman_compression_ = true; | 132 allow_huffman_compression_ = true; |
128 output_stream_.TakeString(output); | 133 output_stream_.TakeString(output); |
129 return true; | 134 return true; |
130 } | 135 } |
131 | 136 |
132 void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) { | 137 void HpackEncoder::ApplyHeaderTableSizeSetting(size_t size_setting) { |
133 if (size_setting == header_table_.settings_size_bound()) { | 138 if (size_setting == header_table_.settings_size_bound()) { |
134 return; | 139 return; |
135 } | 140 } |
136 if (size_setting < header_table_.settings_size_bound()) { | 141 if (size_setting < header_table_.settings_size_bound()) { |
137 min_table_size_setting_received_ = | 142 min_table_size_setting_received_ = |
138 std::min(size_setting, min_table_size_setting_received_); | 143 std::min(size_setting, min_table_size_setting_received_); |
139 } | 144 } |
140 header_table_.SetSettingsHeaderTableSize(size_setting); | 145 header_table_.SetSettingsHeaderTableSize(size_setting); |
141 should_emit_table_size_ = true; | 146 should_emit_table_size_ = true; |
142 } | 147 } |
143 | 148 |
144 void HpackEncoder::EncodeRepresentations(RepresentationIterator* iter, | 149 void HpackEncoder::EncodeRepresentations(RepresentationIterator* iter, |
145 string* output) { | 150 string* output) { |
146 MaybeEmitTableSize(); | 151 MaybeEmitTableSize(); |
147 while (iter->HasNext()) { | 152 while (iter->HasNext()) { |
148 const auto header = iter->Next(); | 153 const auto header = iter->Next(); |
| 154 listener_(header.first, header.second); |
149 const HpackEntry* entry = | 155 const HpackEntry* entry = |
150 header_table_.GetByNameAndValue(header.first, header.second); | 156 header_table_.GetByNameAndValue(header.first, header.second); |
151 if (entry != nullptr) { | 157 if (entry != nullptr) { |
152 EmitIndex(entry); | 158 EmitIndex(entry); |
153 } else if (should_index_(header.first, header.second)) { | 159 } else if (should_index_(header.first, header.second)) { |
154 EmitIndexedLiteral(header); | 160 EmitIndexedLiteral(header); |
155 } else { | 161 } else { |
156 EmitNonIndexedLiteral(header); | 162 EmitNonIndexedLiteral(header); |
157 } | 163 } |
158 } | 164 } |
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
264 end = header_field.second.find('\0', pos); | 270 end = header_field.second.find('\0', pos); |
265 out->push_back( | 271 out->push_back( |
266 std::make_pair(header_field.first, | 272 std::make_pair(header_field.first, |
267 header_field.second.substr( | 273 header_field.second.substr( |
268 pos, end == StringPiece::npos ? end : end - pos))); | 274 pos, end == StringPiece::npos ? end : end - pos))); |
269 pos = end + 1; | 275 pos = end + 1; |
270 } | 276 } |
271 } | 277 } |
272 | 278 |
273 } // namespace net | 279 } // namespace net |
OLD | NEW |