class Protocol::HPACK::Compressor

Responsible for encoding header key-value pairs using HPACK algorithm.

def encode(headers, table_size = @table_size_limit)

Returns:
  • (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)

Returns:
  • (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)

Returns:
  • (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)

Returns:
  • (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