Class: HTTP2::Header::Decompressor

Inherits:
Object
  • Object
show all
Defined in:
lib/http/2/compressor.rb

Overview

Responsible for decoding received headers and maintaining compression context of the opposing peer. Decompressor must be initialized with appropriate starting context based on local role: client or server.

Examples:

server_role = Decompressor.new(:request)
client_role = Decompressor.new(:response)

Instance Method Summary collapse

Constructor Details

#initialize(type) ⇒ Decompressor

Returns a new instance of Decompressor.



420
421
422
# File 'lib/http/2/compressor.rb', line 420

def initialize(type)
  @cc = CompressionContext.new(type)
end

Instance Method Details

#decode(buf) ⇒ Object

Decodes and processes header commands within provided buffer.

Parameters:

  • buf (String)


485
486
487
488
489
# File 'lib/http/2/compressor.rb', line 485

def decode(buf)
  @cc.update_sets
  @cc.process(header(buf)) while !buf.eof?
  @cc.workset.map {|i,header| header}
end

#header(buf) ⇒ Object

Decodes header command from provided buffer.

Parameters:

  • buf (String)


454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# File 'lib/http/2/compressor.rb', line 454

def header(buf)
  peek = buf.getbyte
  buf.seek(-1, IO::SEEK_CUR)

  header = {}
  header[:type], type = HEADREP.select do |t, desc|
    mask = (peek >> desc[:prefix]) << desc[:prefix]
    mask == desc[:pattern]
  end.first

  header[:name] = integer(buf, type[:prefix])
  if header[:type] != :indexed
    header[:name] -= 1

    if header[:name] == -1
      header[:name] = string(buf)
    end

    if header[:type] == :substitution
      header[:index] = integer(buf, 0)
    end

    header[:value] = string(buf)
  end

  header
end

#integer(buf, n) ⇒ Object

Decodes integer value from provided buffer.

Parameters:

  • buf (String)
  • n (Integer)

    number of available bits



428
429
430
431
432
433
434
435
436
437
438
439
440
441
# File 'lib/http/2/compressor.rb', line 428

def integer(buf, n)
  limit = 2**n - 1
  i = !n.zero? ? (buf.getbyte & limit) : 0

  m = 0
  buf.each_byte do |byte|
    i += ((byte & 127) << m)
    m += 7

    break if (byte & 128).zero?
  end if (i == limit)

  i
end

#string(buf) ⇒ String

Decodes string value from provided buffer.

Parameters:

  • buf (String)

Returns:

  • (String)

    UTF-8 encoded string



447
448
449
# File 'lib/http/2/compressor.rb', line 447

def string(buf)
  buf.read(integer(buf, 0)).force_encoding('utf-8')
end