Class: HTTP2::Header::CompressionContext
- Inherits:
-
Object
- Object
- HTTP2::Header::CompressionContext
- Includes:
- Error
- Defined in:
- lib/http/2/compressor.rb
Overview
The set of components used to encode or decode a header set form an encoding context: an encoding context contains a header table and a reference set - there is one encoding context for each direction.
Constant Summary collapse
- REQ_DEFAULTS =
Default request working set as defined by the spec.
[ [':scheme' ,'http' ], [':scheme' ,'https'], [':host' ,'' ], [':path' ,'/' ], [':method' ,'get' ], ['accept' ,'' ], ['accept-charset' ,'' ], ['accept-encoding' ,'' ], ['accept-language' ,'' ], ['cookie' ,'' ], ['if-modified-since' ,'' ], ['keep-alive' ,'' ], ['user-agent' ,'' ], ['proxy-connection' ,'' ], ['referer' ,'' ], ['accept-datetime' ,'' ], ['authorization' ,'' ], ['allow' ,'' ], ['cache-control' ,'' ], ['connection' ,'' ], ['content-length' ,'' ], ['content-md5' ,'' ], ['content-type' ,'' ], ['date' ,'' ], ['expect' ,'' ], ['from' ,'' ], ['if-match' ,'' ], ['if-none-match' ,'' ], ['if-range' ,'' ], ['if-unmodified-since','' ], ['max-forwards' ,'' ], ['pragma' ,'' ], ['proxy-authorization','' ], ['range' ,'' ], ['te' ,'' ], ['upgrade' ,'' ], ['via' ,'' ], ['warning' ,'' ] ]
- RESP_DEFAULTS =
Default response working set as defined by the spec.
[ [':status' ,'200'], ['age' ,'' ], ['cache-control' ,'' ], ['content-length' ,'' ], ['content-type' ,'' ], ['date' ,'' ], ['etag' ,'' ], ['expires' ,'' ], ['last-modified' ,'' ], ['server' ,'' ], ['set-cookie' ,'' ], ['vary' ,'' ], ['via' ,'' ], ['access-control-allow-origin','' ], ['accept-ranges' ,'' ], ['allow' ,'' ], ['connection' ,'' ], ['content-disposition' ,'' ], ['content-encoding' ,'' ], ['content-language' ,'' ], ['content-location' ,'' ], ['content-md5' ,'' ], ['content-range' ,'' ], ['link' ,'' ], ['location' ,'' ], ['p3p' ,'' ], ['pragma' ,'' ], ['proxy-authenticate' ,'' ], ['refresh' ,'' ], ['retry-after' ,'' ], ['strict-transport-security' ,'' ], ['trailer' ,'' ], ['transfer-encoding' ,'' ], ['warning' ,'' ], ['www-authenticate' ,'' ] ]
Instance Attribute Summary collapse
-
#table ⇒ Object
readonly
Current table of header key-value pairs.
-
#workset ⇒ Object
readonly
Current working set of header key-value pairs.
Instance Method Summary collapse
-
#addcmd(header) ⇒ Object
Emits best available command to encode provided header.
-
#initialize(type, limit = 4096) ⇒ CompressionContext
constructor
Initializes compression context with appropriate client/server defaults and maximum size of the header table.
-
#process(cmd) ⇒ Object
Performs differential coding based on provided command type.
-
#removecmd(idx) ⇒ Object
Emits command to remove current index from working set.
-
#update_sets ⇒ Array
First, upon starting the decoding of a new set of headers, the reference set of headers is interpreted into the working set of headers: for each header in the reference set, an entry is added to the working set, containing the header name, its value, and its current index in the header table.
Constructor Details
#initialize(type, limit = 4096) ⇒ CompressionContext
Initializes compression context with appropriate client/server defaults and maximum size of the header table.
112 113 114 115 116 117 |
# File 'lib/http/2/compressor.rb', line 112 def initialize(type, limit = 4096) @type = type @table = (type == :request) ? REQ_DEFAULTS.dup : RESP_DEFAULTS.dup @limit = limit @workset = [] end |
Instance Attribute Details
#table ⇒ Object (readonly)
Current table of header key-value pairs.
102 103 104 |
# File 'lib/http/2/compressor.rb', line 102 def table @table end |
#workset ⇒ Object (readonly)
Current working set of header key-value pairs.
105 106 107 |
# File 'lib/http/2/compressor.rb', line 105 def workset @workset end |
Instance Method Details
#addcmd(header) ⇒ Object
Emits best available command to encode provided header.
196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 |
# File 'lib/http/2/compressor.rb', line 196 def addcmd(header) # check if we have an exact match in header table if idx = @table.index(header) if !active? idx return { name: idx, type: :indexed } end end # check if we have a partial match on header name if idx = @table.index {|(k,_)| k == header.first} # default to incremental indexing cmd = { name: idx, value: header.last, type: :incremental} # TODO: implement literal without indexing strategy # TODO: implement substitution strategy (if it makes sense) # if default? idx # cmd[:type] = :incremental # else # cmd[:type] = :substitution # cmd[:index] = idx # end return cmd end return { name: header.first, value: header.last, type: :incremental } end |
#process(cmd) ⇒ Object
Performs differential coding based on provided command type.
123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 |
# File 'lib/http/2/compressor.rb', line 123 def process(cmd) # indexed representation if cmd[:type] == :indexed # For an indexed representation, the decoder checks whether the index # is present in the working set. If true, the corresponding entry is # removed from the working set. If several entries correspond to this # encoded index, all these entries are removed from the working set. # If the index is not present in the working set, it is used to # retrieve the corresponding header from the header table, and a new # entry is added to the working set representing this header. cur = @workset.find_index {|(i,v)| i == cmd[:name]} if cur @workset.delete_at(cur) else @workset.push [cmd[:name], @table[cmd[:name]]] end else # For a literal representation, a new entry is added to the working # set representing this header. If the literal representation specifies # that the header is to be indexed, the header is added accordingly to # the header table, and its index is included in the entry in the working # set. Otherwise, the entry in the working set contains an undefined index. if cmd[:name].is_a? Integer k,v = @table[cmd[:name]] cmd[:index] ||= cmd[:name] cmd[:value] ||= v cmd[:name] = k end newval = [cmd[:name], cmd[:value]] if cmd[:type] != :noindex size_check cmd case cmd[:type] when :incremental cmd[:index] = @table.size when :substitution if @table[cmd[:index]].nil? raise HeaderException.new("invalid index") end when :prepend @table = [newval] + @table end @table[cmd[:index]] = newval end @workset.push [cmd[:index], newval] end end |
#removecmd(idx) ⇒ Object
Emits command to remove current index from working set.
227 228 229 |
# File 'lib/http/2/compressor.rb', line 227 def removecmd(idx) {name: idx, type: :indexed} end |
#update_sets ⇒ Array
First, upon starting the decoding of a new set of headers, the reference set of headers is interpreted into the working set of headers: for each header in the reference set, an entry is added to the working set, containing the header name, its value, and its current index in the header table.
185 186 187 188 189 190 191 |
# File 'lib/http/2/compressor.rb', line 185 def update_sets # new refset is the the workset sans headers not in header table refset = @workset.reject {|(i,h)| !@table.include? h} # new workset is the refset with index of each header in header table @workset = refset.collect {|(i,h)| [@table.find_index(h), h]} end |