| 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 |