class Protocol::HPACK::Compressor
Responsible for encoding header key-value pairs using HPACK algorithm.
def encode(headers, table_size = @table_size_limit)
-
(Buffer)
-
Parameters:
-
headers
(Array
) -- +[[name, value], ...]+
def encode(headers, table_size = @table_size_limit) if table_size and table_size != @context.table_size command = @context.change_table_size(table_size) write_header(command) end commands = @context.encode(headers) commands.each do |command| write_header(command) end return @buffer end
def huffman
def huffman @context.huffman end
def initialize(buffer, context = Context.new, table_size_limit: nil)
def initialize(buffer, context = Context.new, table_size_limit: nil) @buffer = buffer @context = context @table_size_limit = table_size_limit end
def write_bytes(bytes)
def write_bytes(bytes) @buffer << bytes end
def write_header(command)
-
(Buffer)
-
Parameters:
-
buffer
(String
) -- -
h
(Hash
) -- header command
def write_header(command) representation = HEADER_REPRESENTATION[command[:type]] first = @buffer.bytesize case command[:type] when :indexed write_integer(command[:name] + 1, representation[:prefix]) when :change_table_size write_integer(command[:value], representation[:prefix]) else if command[:name].is_a? Integer write_integer(command[:name] + 1, representation[:prefix]) else write_integer(0, representation[:prefix]) write_string(command[:name]) end write_string(command[:value]) end # set header representation pattern on first byte @buffer.setbyte(first, @buffer.getbyte(first) | representation[:pattern]) end
def write_integer(value, bits)
-
(String)
- binary string
Parameters:
-
bits
(Integer
) -- number of available bits -
value
(Integer
) -- value to encode
def write_integer(value, bits) limit = (1 << bits) - 1 return @buffer << value if value < limit @buffer << limit unless bits.zero? value -= limit while value >= 128 @buffer << ((value & 0x7f) + 128) value /= 128 end @buffer << value end
def write_string(string, huffman = self.huffman)
-
(String)
- binary string
Parameters:
-
string
(String
) --
def write_string(string, huffman = self.huffman) if huffman != :never encoded = Huffman.encode(string) if huffman == :shorter and encoded.bytesize >= string.bytesize encoded = nil end end if encoded first = @buffer.bytesize write_integer(encoded.bytesize, 7) write_bytes(encoded.b) @buffer.setbyte(first, @buffer.getbyte(first).ord | 0x80) else write_integer(string.bytesize, 7) write_bytes(string.b) end end