Class: HTTP::HPACK::Decompressor
- Inherits:
-
Object
- Object
- HTTP::HPACK::Decompressor
- Defined in:
- lib/http/hpack/decompressor.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.
Instance Attribute Summary collapse
-
#buffer ⇒ Object
readonly
Returns the value of attribute buffer.
-
#context ⇒ Object
readonly
Returns the value of attribute context.
-
#offset ⇒ Object
readonly
Returns the value of attribute offset.
Instance Method Summary collapse
-
#decode(list = []) ⇒ Array
Decodes and processes header commands within provided buffer.
- #end? ⇒ Boolean
-
#initialize(buffer, context = Context.new) ⇒ Decompressor
constructor
A new instance of Decompressor.
- #peek_byte ⇒ Object
- #read_byte ⇒ Object
- #read_bytes(length) ⇒ Object
-
#read_header ⇒ Hash
Decodes header command from provided buffer.
-
#read_integer(bits) ⇒ Integer
Decodes integer value from provided buffer.
-
#read_string ⇒ String
Decodes string value from provided buffer.
Constructor Details
#initialize(buffer, context = Context.new) ⇒ Decompressor
Returns a new instance of Decompressor.
31 32 33 34 35 |
# File 'lib/http/hpack/decompressor.rb', line 31 def initialize(buffer, context = Context.new) @buffer = buffer @context = context @offset = 0 end |
Instance Attribute Details
#buffer ⇒ Object (readonly)
Returns the value of attribute buffer.
37 38 39 |
# File 'lib/http/hpack/decompressor.rb', line 37 def buffer @buffer end |
#context ⇒ Object (readonly)
Returns the value of attribute context.
38 39 40 |
# File 'lib/http/hpack/decompressor.rb', line 38 def context @context end |
#offset ⇒ Object (readonly)
Returns the value of attribute offset.
39 40 41 |
# File 'lib/http/hpack/decompressor.rb', line 39 def offset @offset end |
Instance Method Details
#decode(list = []) ⇒ Array
Decodes and processes header commands within provided buffer.
143 144 145 146 147 148 149 150 151 |
# File 'lib/http/hpack/decompressor.rb', line 143 def decode(list = []) while !end? if pair = @context.decode(read_header) list << pair end end return list end |
#end? ⇒ Boolean
41 42 43 |
# File 'lib/http/hpack/decompressor.rb', line 41 def end? @offset >= @buffer.bytesize end |
#peek_byte ⇒ Object
54 55 56 |
# File 'lib/http/hpack/decompressor.rb', line 54 def peek_byte @buffer.getbyte(@offset) end |
#read_byte ⇒ Object
45 46 47 48 49 50 51 |
# File 'lib/http/hpack/decompressor.rb', line 45 def read_byte if byte = @buffer.getbyte(@offset) @offset += 1 end return byte end |
#read_bytes(length) ⇒ Object
58 59 60 61 62 63 64 |
# File 'lib/http/hpack/decompressor.rb', line 58 def read_bytes(length) slice = @buffer.byteslice(@offset, length) @offset += length return slice end |
#read_header ⇒ Hash
Decodes header command from provided buffer.
107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/http/hpack/decompressor.rb', line 107 def read_header pattern = peek_byte header = {} header[:type], type = HEADER_REPRESENTATION.find do |_t, desc| mask = (pattern >> desc[:prefix]) << desc[:prefix] mask == desc[:pattern] end raise CompressionError unless header[:type] header[:name] = read_integer(type[:prefix]) case header[:type] when :indexed raise CompressionError if header[:name].zero? header[:name] -= 1 when :changetablesize header[:value] = header[:name] else if (header[:name]).zero? header[:name] = read_string else header[:name] -= 1 end header[:value] = read_string end return header end |
#read_integer(bits) ⇒ Integer
Decodes integer value from provided buffer.
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
# File 'lib/http/hpack/decompressor.rb', line 70 def read_integer(bits) limit = 2**bits - 1 value = !bits.zero? ? (read_byte & limit) : 0 shift = 0 while byte = read_byte value += ((byte & 127) << shift) shift += 7 break if (byte & 128).zero? end if (value == limit) return value end |
#read_string ⇒ String
Decodes string value from provided buffer.
90 91 92 93 94 95 96 97 98 99 100 101 |
# File 'lib/http/hpack/decompressor.rb', line 90 def read_string huffman = (peek_byte & 0x80) == 0x80 length = read_integer(7) string = read_bytes(length) raise CompressionError, "Invalid string length, got #{string.bytesize}, expecting #{length}!" unless string.bytesize == length string = Huffman.new.decode(string) if huffman return string.force_encoding(Encoding::UTF_8) end |