class Frame
Definitions
VALID_STREAM_ID = 0..0x7fffffff
Stream Identifier cannot be bigger than this: https://http2.github.stream/http2-spec/#rfc.section.4.1
VALID_LENGTH = 0..0xffffff
The absolute maximum bounds for the length field:
LENGTH_HISHIFT = 16
Used for generating 24-bit frame length:
TYPE = nil
The base class does not have any specific type index:
def initialize(stream_id = 0, flags = 0, type = self.class::TYPE, length = nil, payload = nil)
Implementation
def initialize(stream_id = 0, flags = 0, type = self.class::TYPE, length = nil, payload = nil)
@stream_id = stream_id
@flags = flags
@type = type
@length = length
@payload = payload
end
def connection?
Check if frame is a connection frame: SETTINGS, PING, GOAWAY, and any frame addressed to stream ID = 0.
Implementation
def connection?
@stream_id.zero?
end
def header
Generates common 9-byte frame header.
- http://tools.ietf.org/html/draft-ietf-httpbis-http2-16#section-4.1
Implementation
def header
unless VALID_LENGTH.include? @length
raise ProtocolError, "Invalid frame length: #{@length.inspect}"
end
unless VALID_STREAM_ID.include? @stream_id
raise ProtocolError, "Invalid stream identifier: #{@stream_id.inspect}"
end
[
# These are guaranteed correct due to the length check above.
@length >> LENGTH_HISHIFT,
@length & LENGTH_LOMASK,
@type,
@flags,
@stream_id
].pack(HEADER_FORMAT)
end
def self.parse_header(buffer)
Decodes common 9-byte header.
Implementation
def self.parse_header(buffer)
length_hi, length_lo, type, flags, stream_id = buffer.unpack(HEADER_FORMAT)
length = (length_hi << LENGTH_HISHIFT) | length_lo
stream_id = stream_id & STREAM_ID_MASK
# puts "parse_header: length=#{length} type=#{type} flags=#{flags} stream_id=#{stream_id}"
return length, type, flags, stream_id
end