Class: Protocol::HTTP2::Frame
- Inherits:
-
Object
- Object
- Protocol::HTTP2::Frame
show all
- Includes:
- Comparable
- Defined in:
- lib/protocol/http2/frame.rb
Constant Summary
collapse
- VALID_STREAM_ID =
0..0x7fffffff
- VALID_LENGTH =
The absolute maximum bounds for the length field:
0..0xffffff
- LENGTH_HISHIFT =
Used for generating 24-bit frame length:
16
- LENGTH_LOMASK =
0xFFFF
- TYPE =
The base class does not have any specific type index:
nil
"CnCCN".freeze
- STREAM_ID_MASK =
0x7fffffff
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(stream_id = 0, flags = 0, type = self.class::TYPE, length = nil, payload = nil) ⇒ Frame
Returns a new instance of Frame.
38
39
40
41
42
43
44
|
# File 'lib/protocol/http2/frame.rb', line 38
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
|
Instance Attribute Details
#flags ⇒ Object
Returns the value of attribute flags.
72
73
74
|
# File 'lib/protocol/http2/frame.rb', line 72
def flags
@flags
end
|
#length ⇒ Object
The generic frame header uses the following binary representation:
-----------------------------------------------
| Length (24) | ---------------
—————---------------
| Type (8) | Flags (8) | -
————----------------
——————————-+ |R| Stream Identifier (31) | ==============================================================+ | Frame Payload (0…) … ---------------------------------------------------------------
70
71
72
|
# File 'lib/protocol/http2/frame.rb', line 70
def length
@length
end
|
#payload ⇒ Object
Returns the value of attribute payload.
74
75
76
|
# File 'lib/protocol/http2/frame.rb', line 74
def payload
@payload
end
|
#stream_id ⇒ Object
Returns the value of attribute stream_id.
73
74
75
|
# File 'lib/protocol/http2/frame.rb', line 73
def stream_id
@stream_id
end
|
#type ⇒ Object
Returns the value of attribute type.
71
72
73
|
# File 'lib/protocol/http2/frame.rb', line 71
def type
@type
end
|
Class Method Details
Decodes common 9-byte header.
138
139
140
141
142
143
144
145
146
|
# File 'lib/protocol/http2/frame.rb', line 138
def self.(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
return length, type, flags, stream_id
end
|
Instance Method Details
#<=>(other) ⇒ Object
50
51
52
|
# File 'lib/protocol/http2/frame.rb', line 50
def <=> other
to_ary <=> other.to_ary
end
|
#apply(connection) ⇒ Object
199
200
201
|
# File 'lib/protocol/http2/frame.rb', line 199
def apply(connection)
connection.receive_frame(self)
end
|
#clear_flags(mask) ⇒ Object
93
94
95
|
# File 'lib/protocol/http2/frame.rb', line 93
def clear_flags(mask)
@flags &= ~mask
end
|
#connection? ⇒ Boolean
Check if frame is a connection frame: SETTINGS, PING, GOAWAY, and any frame addressed to stream ID = 0.
105
106
107
|
# File 'lib/protocol/http2/frame.rb', line 105
def connection?
@stream_id.zero?
end
|
#flag_set?(mask) ⇒ Boolean
97
98
99
|
# File 'lib/protocol/http2/frame.rb', line 97
def flag_set?(mask)
@flags & mask != 0
end
|
Generates common 9-byte frame header.
#inspect ⇒ Object
203
204
205
|
# File 'lib/protocol/http2/frame.rb', line 203
def inspect
"\#<#{self.class} stream_id=#{@stream_id} flags=#{@flags} payload=#{self.unpack}>"
end
|
#pack(payload, maximum_size: nil) ⇒ Object
80
81
82
83
84
85
86
87
|
# File 'lib/protocol/http2/frame.rb', line 80
def pack(payload, maximum_size: nil)
@payload = payload
@length = payload.bytesize
if maximum_size and @length > maximum_size
raise ProtocolError, "Frame length bigger than maximum allowed: #{@length} > #{maximum_size}"
end
end
|
#read(stream, maximum_frame_size = MAXIMUM_ALLOWED_FRAME_SIZE) ⇒ Object
165
166
167
168
169
170
171
172
173
|
# File 'lib/protocol/http2/frame.rb', line 165
def read(stream, maximum_frame_size = MAXIMUM_ALLOWED_FRAME_SIZE)
(stream) unless @length
if @length > maximum_frame_size
raise FrameSizeError, "#{self.class} (type=#{@type}) frame length #{@length} exceeds maximum frame size #{maximum_frame_size}!"
end
read_payload(stream)
end
|
148
149
150
151
152
153
154
155
|
# File 'lib/protocol/http2/frame.rb', line 148
def (stream)
if buffer = stream.read(9) and buffer.bytesize == 9
@length, @type, @flags, @stream_id = Frame.(buffer)
else
raise EOFError, "Could not read frame header!"
end
end
|
#read_payload(stream) ⇒ Object
157
158
159
160
161
162
163
|
# File 'lib/protocol/http2/frame.rb', line 157
def read_payload(stream)
if payload = stream.read(@length) and payload.bytesize == @length
@payload = payload
else
raise EOFError, "Could not read frame payload!"
end
end
|
#set_flags(mask) ⇒ Object
89
90
91
|
# File 'lib/protocol/http2/frame.rb', line 89
def set_flags(mask)
@flags |= mask
end
|
#to_ary ⇒ Object
54
55
56
|
# File 'lib/protocol/http2/frame.rb', line 54
def to_ary
[@length, @type, @flags, @stream_id, @payload]
end
|
#unpack ⇒ Object
76
77
78
|
# File 'lib/protocol/http2/frame.rb', line 76
def unpack
@payload
end
|
#valid_type? ⇒ Boolean
46
47
48
|
# File 'lib/protocol/http2/frame.rb', line 46
def valid_type?
@type == self.class::TYPE
end
|
#write(stream) ⇒ Object
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
|
# File 'lib/protocol/http2/frame.rb', line 183
def write(stream)
if @payload.nil?
if @length != 0
raise ProtocolError, "Invalid frame length: #{@length} != 0"
end
else
if @length != @payload.bytesize
raise ProtocolError, "Invalid payload size: #{@length} != #{@payload.bytesize}"
end
end
self.(stream)
self.write_payload(stream)
end
|
175
176
177
|
# File 'lib/protocol/http2/frame.rb', line 175
def (stream)
stream.write self.
end
|
#write_payload(stream) ⇒ Object
179
180
181
|
# File 'lib/protocol/http2/frame.rb', line 179
def write_payload(stream)
stream.write(@payload) if @payload
end
|