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 3 // found in the LICENSE file. 4 5 #ifndef NET_SPDY_HPACK_ENCODER_H_ 6 #define NET_SPDY_HPACK_ENCODER_H_ 7 8 #include <map> 9 #include <string> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/macros.h" 14 #include "base/strings/string_piece.h" 15 #include "net/base/net_export.h" 16 #include "net/spdy/hpack_header_table.h" 17 #include "net/spdy/hpack_output_stream.h" 18 19 // An HpackEncoder encodes header sets as outlined in 20 // http://tools.ietf.org/html/draft-ietf-httpbis-header-compression-07 21 22 namespace net { 23 24 class HpackHuffmanTable; 25 26 namespace test { 27 class HpackEncoderPeer; 28 } // namespace test 29 30 class NET_EXPORT_PRIVATE HpackEncoder { 31 public: 32 friend class test::HpackEncoderPeer; 33 34 // |table| is an initialized HPACK Huffman table, having an 35 // externally-managed lifetime which spans beyond HpackEncoder. 36 explicit HpackEncoder(const HpackHuffmanTable& table); 37 ~HpackEncoder(); 38 39 // Encodes the given header set into the given string. Returns 40 // whether or not the encoding was successful. 41 bool EncodeHeaderSet(const std::map<std::string, std::string>& header_set, 42 std::string* output); 43 44 // Encodes the given header set into the given string. Only non-indexed 45 // literal representations are emitted, bypassing the header table. Huffman 46 // coding is also not used. Returns whether the encoding was successful. 47 // TODO(jgraettinger): Enable Huffman coding once the table as stablized. 48 bool EncodeHeaderSetWithoutCompression( 49 const std::map<std::string, std::string>& header_set, 50 std::string* output); 51 52 // Called upon a change to SETTINGS_HEADER_TABLE_SIZE. Specifically, this 53 // is to be called after receiving (and sending an acknowledgement for) a 54 // SETTINGS_HEADER_TABLE_SIZE update from the remote decoding endpoint. 55 void ApplyHeaderTableSizeSetting(size_t size_setting) { 56 header_table_.SetSettingsHeaderTableSize(size_setting); 57 } 58 59 // Sets externally-owned storage for aggregating character counts of emitted 60 // literal representations. 61 void SetCharCountsStorage(std::vector<size_t>* char_counts, 62 size_t* total_char_counts); 63 64 private: 65 typedef std::pair<base::StringPiece, base::StringPiece> Representation; 66 typedef std::vector<Representation> Representations; 67 68 // Emits a static/dynamic indexed representation (Section 4.2). 69 void EmitDynamicIndex(HpackEntry* entry); 70 void EmitStaticIndex(HpackEntry* entry); 71 72 // Emits a literal representation (Section 4.3). 73 void EmitIndexedLiteral(const Representation& representation); 74 void EmitNonIndexedLiteral(const Representation& representation); 75 void EmitLiteral(const Representation& representation); 76 77 // Emits a Huffman or identity string (whichever is smaller). 78 void EmitString(base::StringPiece str); 79 80 void UpdateCharacterCounts(base::StringPiece str); 81 82 // Determines the representation delta required to encode |header_set| in 83 // the current header table context. Entries in the reference set are 84 // enumerated and marked with membership in the current |header_set|. 85 // Representations which must be explicitly emitted are returned. 86 Representations DetermineEncodingDelta( 87 const std::map<std::string, std::string>& header_set); 88 89 // Crumbles a cookie header into sorted, de-duplicated crumbs. 90 static void CookieToCrumbs(const Representation& cookie, 91 Representations* crumbs_out); 92 93 HpackHeaderTable header_table_; 94 HpackOutputStream output_stream_; 95 96 bool allow_huffman_compression_; 97 const HpackHuffmanTable& huffman_table_; 98 99 // Externally-owned, nullable storage for character counts of literals. 100 std::vector<size_t>* char_counts_; 101 size_t* total_char_counts_; 102 103 DISALLOW_COPY_AND_ASSIGN(HpackEncoder); 104 }; 105 106 } // namespace net 107 108 #endif // NET_SPDY_HPACK_ENCODER_H_ 109