| 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_encoder.h" | 5 #include "net/spdy/hpack_encoder.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "net/spdy/hpack_header_table.h" | 10 #include "net/spdy/hpack_header_table.h" |
| (...skipping 30 matching lines...) Expand all Loading... |
| 41 StringPiece(it->first), StringPiece(it->second))); | 41 StringPiece(it->first), StringPiece(it->second))); |
| 42 } else { | 42 } else { |
| 43 regular_headers.push_back(make_pair( | 43 regular_headers.push_back(make_pair( |
| 44 StringPiece(it->first), StringPiece(it->second))); | 44 StringPiece(it->first), StringPiece(it->second))); |
| 45 } | 45 } |
| 46 } | 46 } |
| 47 | 47 |
| 48 // Encode pseudo-headers. | 48 // Encode pseudo-headers. |
| 49 for (Representations::const_iterator it = pseudo_headers.begin(); | 49 for (Representations::const_iterator it = pseudo_headers.begin(); |
| 50 it != pseudo_headers.end(); ++it) { | 50 it != pseudo_headers.end(); ++it) { |
| 51 HpackEntry* entry = header_table_.GetByNameAndValue(it->first, it->second); | 51 const HpackEntry* entry = |
| 52 header_table_.GetByNameAndValue(it->first, it->second); |
| 52 if (entry != NULL) { | 53 if (entry != NULL) { |
| 53 EmitIndex(entry); | 54 EmitIndex(entry); |
| 54 } else { | 55 } else { |
| 55 if (it->first == ":authority") { | 56 if (it->first == ":authority") { |
| 56 // :authority is always present and rarely changes, and has moderate | 57 // :authority is always present and rarely changes, and has moderate |
| 57 // length, therefore it makes a lot of sense to index (insert in the | 58 // length, therefore it makes a lot of sense to index (insert in the |
| 58 // header table). | 59 // header table). |
| 59 EmitIndexedLiteral(*it); | 60 EmitIndexedLiteral(*it); |
| 60 } else { | 61 } else { |
| 61 // Most common pseudo-header fields are represented in the static table, | 62 // Most common pseudo-header fields are represented in the static table, |
| 62 // while uncommon ones are small, so do not index them. | 63 // while uncommon ones are small, so do not index them. |
| 63 EmitNonIndexedLiteral(*it); | 64 EmitNonIndexedLiteral(*it); |
| 64 } | 65 } |
| 65 } | 66 } |
| 66 } | 67 } |
| 67 | 68 |
| 68 // Encode regular headers that are already in the header table first, | 69 // Encode regular headers that are already in the header table first, |
| 69 // save the rest into another vector. This way we avoid evicting an entry | 70 // save the rest into another vector. This way we avoid evicting an entry |
| 70 // from the header table before it can be used. | 71 // from the header table before it can be used. |
| 71 Representations literal_headers; | 72 Representations literal_headers; |
| 72 for (Representations::const_iterator it = regular_headers.begin(); | 73 for (Representations::const_iterator it = regular_headers.begin(); |
| 73 it != regular_headers.end(); ++it) { | 74 it != regular_headers.end(); ++it) { |
| 74 HpackEntry* entry = header_table_.GetByNameAndValue(it->first, it->second); | 75 const HpackEntry* entry = |
| 76 header_table_.GetByNameAndValue(it->first, it->second); |
| 75 if (entry != NULL) { | 77 if (entry != NULL) { |
| 76 EmitIndex(entry); | 78 EmitIndex(entry); |
| 77 } else { | 79 } else { |
| 78 literal_headers.push_back(*it); | 80 literal_headers.push_back(*it); |
| 79 } | 81 } |
| 80 } | 82 } |
| 81 | 83 |
| 82 // Encode the remaining header fields, while inserting them in the header | 84 // Encode the remaining header fields, while inserting them in the header |
| 83 // table. | 85 // table. |
| 84 for (Representations::const_iterator it = literal_headers.begin(); | 86 for (Representations::const_iterator it = literal_headers.begin(); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 98 for (std::map<string, string>::const_iterator it = header_set.begin(); | 100 for (std::map<string, string>::const_iterator it = header_set.begin(); |
| 99 it != header_set.end(); ++it) { | 101 it != header_set.end(); ++it) { |
| 100 // Note that cookies are not crumbled in this case. | 102 // Note that cookies are not crumbled in this case. |
| 101 EmitNonIndexedLiteral(*it); | 103 EmitNonIndexedLiteral(*it); |
| 102 } | 104 } |
| 103 allow_huffman_compression_ = true; | 105 allow_huffman_compression_ = true; |
| 104 output_stream_.TakeString(output); | 106 output_stream_.TakeString(output); |
| 105 return true; | 107 return true; |
| 106 } | 108 } |
| 107 | 109 |
| 108 void HpackEncoder::EmitIndex(HpackEntry* entry) { | 110 void HpackEncoder::EmitIndex(const HpackEntry* entry) { |
| 109 output_stream_.AppendPrefix(kIndexedOpcode); | 111 output_stream_.AppendPrefix(kIndexedOpcode); |
| 110 output_stream_.AppendUint32(header_table_.IndexOf(entry)); | 112 output_stream_.AppendUint32(header_table_.IndexOf(entry)); |
| 111 } | 113 } |
| 112 | 114 |
| 113 void HpackEncoder::EmitIndexedLiteral(const Representation& representation) { | 115 void HpackEncoder::EmitIndexedLiteral(const Representation& representation) { |
| 114 output_stream_.AppendPrefix(kLiteralIncrementalIndexOpcode); | 116 output_stream_.AppendPrefix(kLiteralIncrementalIndexOpcode); |
| 115 EmitLiteral(representation); | 117 EmitLiteral(representation); |
| 116 header_table_.TryAddEntry(representation.first, representation.second); | 118 header_table_.TryAddEntry(representation.first, representation.second); |
| 117 } | 119 } |
| 118 | 120 |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 194 pos++; | 196 pos++; |
| 195 } | 197 } |
| 196 } | 198 } |
| 197 // Sort crumbs and remove duplicates. | 199 // Sort crumbs and remove duplicates. |
| 198 std::sort(out->begin() + prior_size, out->end()); | 200 std::sort(out->begin() + prior_size, out->end()); |
| 199 out->erase(std::unique(out->begin() + prior_size, out->end()), | 201 out->erase(std::unique(out->begin() + prior_size, out->end()), |
| 200 out->end()); | 202 out->end()); |
| 201 } | 203 } |
| 202 | 204 |
| 203 } // namespace net | 205 } // namespace net |
| OLD | NEW |