class Plum::HPACK::Encoder

Public Class Methods

new(dynamic_table_limit, indexing: true, huffman: true) click to toggle source
Calls superclass method Plum::HPACK::Context::new
# File lib/plum/hpack/encoder.rb, line 8
def initialize(dynamic_table_limit, indexing: true, huffman: true)
  super(dynamic_table_limit)
  @indexing = indexing
  @huffman = huffman
end

Public Instance Methods

encode(headers) click to toggle source
# File lib/plum/hpack/encoder.rb, line 13
def encode(headers)
  out = "".b
  headers.each do |name, value|
    name = name.to_s
    value = value.to_s
    if index = search(name, value)
      out << encode_indexed(index)
    elsif index = search_half(name)
      out << encode_half_indexed(index, value)
    else
      out << encode_literal(name, value)
    end
  end
  out
end

Private Instance Methods

encode_half_indexed(index, value) click to toggle source

------------—+ | 0 | 1 | Index (6+) | -------------------------- | H | Value Length (7+) | ---—————————+ | Value String (Length octets) | -------------------------------

# File lib/plum/hpack/encoder.rb, line 58
def encode_half_indexed(index, value)
  if @indexing
    store(fetch(index)[0], value)
    fb = encode_integer(index, 6, 0b01000000)
  else
    fb = encode_integer(index, 4, 0b00000000)
  end
  fb << encode_string(value)
end
encode_indexed(index) click to toggle source

------------—+ | 1 | Index (7+) | ---—————————+

# File lib/plum/hpack/encoder.rb, line 71
def encode_indexed(index)
  encode_integer(index, 7, 0b10000000)
end
encode_integer(value, prefix_length, hmask) click to toggle source
# File lib/plum/hpack/encoder.rb, line 75
def encode_integer(value, prefix_length, hmask)
  mask = (1 << prefix_length) - 1

  if value < mask
    (value + hmask).chr.force_encoding(Encoding::BINARY)
  else
    vals = [mask + hmask]
    value -= mask
    while value >= mask
      vals << (value % 0x80) + 0x80
      value /= 0x80
    end
    vals << value
    vals.pack("C*")
  end
end
encode_literal(name, value) click to toggle source

------------—+ | 0 | 1 | 0 | -------------------------- | H | Name Length (7+) | ---—————————+ | Name String (Length octets) | ---—————————+ | H | Value Length (7+) | ---—————————+ | Value String (Length octets) | -------------------------------

# File lib/plum/hpack/encoder.rb, line 41
def encode_literal(name, value)
  if @indexing
    store(name, value)
    fb = "\x40"
  else
    fb = "\x00"
  end
  (fb + encode_string(name)) << encode_string(value)
end
encode_string(str) click to toggle source
# File lib/plum/hpack/encoder.rb, line 92
def encode_string(str)
  if @huffman
    hs = encode_string_huffman(str)
    ps = encode_string_plain(str)
    hs.bytesize < ps.bytesize ? hs : ps
  else
    encode_string_plain(str)
  end
end
encode_string_huffman(str) click to toggle source
# File lib/plum/hpack/encoder.rb, line 106
def encode_string_huffman(str)
  huffman_str = Huffman.encode(str)
  encode_integer(huffman_str.bytesize, 7, 0b10000000) << huffman_str
end
encode_string_plain(str) click to toggle source
# File lib/plum/hpack/encoder.rb, line 102
def encode_string_plain(str)
  encode_integer(str.bytesize, 7, 0b00000000) << str
end