bayserver-docker-http 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/lib/baykit/bayserver/docker/http/h1/command/cmd_content.rb +46 -0
  3. data/lib/baykit/bayserver/docker/http/h1/command/cmd_end_content.rb +37 -0
  4. data/lib/baykit/bayserver/docker/http/h1/command/cmd_header.rb +306 -0
  5. data/lib/baykit/bayserver/docker/http/h1/command/package.rb +3 -0
  6. data/lib/baykit/bayserver/docker/http/h1/h1_command.rb +19 -0
  7. data/lib/baykit/bayserver/docker/http/h1/h1_command_handler.rb +31 -0
  8. data/lib/baykit/bayserver/docker/http/h1/h1_command_unpacker.rb +58 -0
  9. data/lib/baykit/bayserver/docker/http/h1/h1_inbound_handler.rb +371 -0
  10. data/lib/baykit/bayserver/docker/http/h1/h1_packet.rb +28 -0
  11. data/lib/baykit/bayserver/docker/http/h1/h1_packet_factory.rb +21 -0
  12. data/lib/baykit/bayserver/docker/http/h1/h1_packet_unpacker.rb +180 -0
  13. data/lib/baykit/bayserver/docker/http/h1/h1_protocol_handler.rb +66 -0
  14. data/lib/baykit/bayserver/docker/http/h1/h1_type.rb +18 -0
  15. data/lib/baykit/bayserver/docker/http/h1/h1_warp_handler.rb +228 -0
  16. data/lib/baykit/bayserver/docker/http/h1/package.rb +11 -0
  17. data/lib/baykit/bayserver/docker/http/h2/command/cmd_data.rb +65 -0
  18. data/lib/baykit/bayserver/docker/http/h2/command/cmd_go_away.rb +67 -0
  19. data/lib/baykit/bayserver/docker/http/h2/command/cmd_headers.rb +108 -0
  20. data/lib/baykit/bayserver/docker/http/h2/command/cmd_ping.rb +50 -0
  21. data/lib/baykit/bayserver/docker/http/h2/command/cmd_preface.rb +51 -0
  22. data/lib/baykit/bayserver/docker/http/h2/command/cmd_priority.rb +59 -0
  23. data/lib/baykit/bayserver/docker/http/h2/command/cmd_rst_stream.rb +50 -0
  24. data/lib/baykit/bayserver/docker/http/h2/command/cmd_settings.rb +98 -0
  25. data/lib/baykit/bayserver/docker/http/h2/command/cmd_window_update.rb +53 -0
  26. data/lib/baykit/bayserver/docker/http/h2/command/package.rb +9 -0
  27. data/lib/baykit/bayserver/docker/http/h2/h2_command.rb +42 -0
  28. data/lib/baykit/bayserver/docker/http/h2/h2_command_handler.rb +29 -0
  29. data/lib/baykit/bayserver/docker/http/h2/h2_command_unpacker.rb +73 -0
  30. data/lib/baykit/bayserver/docker/http/h2/h2_error_code.rb +53 -0
  31. data/lib/baykit/bayserver/docker/http/h2/h2_flags.rb +82 -0
  32. data/lib/baykit/bayserver/docker/http/h2/h2_inbound_handler.rb +417 -0
  33. data/lib/baykit/bayserver/docker/http/h2/h2_packet.rb +204 -0
  34. data/lib/baykit/bayserver/docker/http/h2/h2_packet_factory.rb +21 -0
  35. data/lib/baykit/bayserver/docker/http/h2/h2_packet_unpacker.rb +224 -0
  36. data/lib/baykit/bayserver/docker/http/h2/h2_protocol_handler.rb +58 -0
  37. data/lib/baykit/bayserver/docker/http/h2/h2_settings.rb +42 -0
  38. data/lib/baykit/bayserver/docker/http/h2/h2_type.rb +26 -0
  39. data/lib/baykit/bayserver/docker/http/h2/h2_warp_handler.rb +142 -0
  40. data/lib/baykit/bayserver/docker/http/h2/header_block.rb +191 -0
  41. data/lib/baykit/bayserver/docker/http/h2/header_block_analyzer.rb +88 -0
  42. data/lib/baykit/bayserver/docker/http/h2/header_block_builder.rb +68 -0
  43. data/lib/baykit/bayserver/docker/http/h2/header_table.rb +167 -0
  44. data/lib/baykit/bayserver/docker/http/h2/huffman/hnode.rb +28 -0
  45. data/lib/baykit/bayserver/docker/http/h2/huffman/htree.rb +339 -0
  46. data/lib/baykit/bayserver/docker/http/h2/package.rb +17 -0
  47. data/lib/baykit/bayserver/docker/http/htp_docker.rb +23 -0
  48. data/lib/baykit/bayserver/docker/http/htp_port_docker.rb +107 -0
  49. data/lib/baykit/bayserver/docker/http/htp_warp_docker.rb +125 -0
  50. data/lib/baykit/bayserver/docker/http/htp_warp_ship_helper.rb +19 -0
  51. data/lib/baykit/bayserver/docker/http/package.rb +6 -0
  52. metadata +106 -0
@@ -0,0 +1,224 @@
1
+ require 'baykit/bayserver/protocol/packet_unpacker'
2
+ require 'baykit/bayserver/agent/next_socket_action'
3
+ require 'baykit/bayserver/util/simple_buffer'
4
+
5
+
6
+ module Baykit
7
+ module BayServer
8
+ module Docker
9
+ module Http
10
+ module H2
11
+ class H2PacketUnPacker < Baykit::BayServer::Protocol::PacketUnPacker
12
+
13
+ include Baykit::BayServer::Agent
14
+ include Baykit::BayServer::Protocol
15
+ include Baykit::BayServer::Docker::Http
16
+ include Baykit::BayServer::Util
17
+
18
+ class FrameHeaderItem
19
+ attr :start
20
+ attr :len
21
+ attr_accessor :pos
22
+
23
+ def initialize(start, len)
24
+ @start = start
25
+ @len = len
26
+ @pos = 0
27
+ end
28
+
29
+ def get(buf, index)
30
+ return buf.buf[@start + index].codepoints[0]
31
+ end
32
+ end
33
+
34
+ STATE_READ_LENGTH = 1
35
+ STATE_READ_TYPE = 2
36
+ STATE_READ_FLAGS = 3
37
+ STATE_READ_STREAM_IDENTIFIER = 4
38
+ STATE_READ_FLAME_PAYLOAD = 5
39
+ STATE_END = 6
40
+
41
+ FRAME_LEN_LENGTH = 3
42
+ FRAME_LEN_TYPE = 1
43
+ FRAME_LEN_FLAGS = 1
44
+ FRAME_LEN_STREAM_IDENTIFIER = 4
45
+
46
+ FLAGS_END_STREAM = 0x1
47
+ FLAGS_END_HEADERS = 0x4
48
+ FLAGS_PADDED = 0x8
49
+ FLAGS_PRIORITY = 0x20
50
+
51
+ CONNECTION_PREFACE = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n"
52
+
53
+ attr :state
54
+ attr :tmp_buf
55
+ attr :item
56
+ attr :preface_read
57
+ attr :type
58
+ attr :payload_len
59
+ attr :flags
60
+ attr :stream_id
61
+
62
+ attr :cmd_unpacker
63
+ attr :pkt_store
64
+ attr :server_mode
65
+
66
+ attr :cont_len
67
+ attr :read_bytes
68
+ attr :pos
69
+
70
+ def initialize(cmd_unpacker, pkt_store, server_mode)
71
+ @cmd_unpacker = cmd_unpacker
72
+ @pkt_store = pkt_store
73
+ @server_mode = server_mode
74
+ @tmp_buf = SimpleBuffer.new
75
+ reset
76
+ end
77
+
78
+ def reset()
79
+ reset_state()
80
+ @preface_read = false
81
+ end
82
+
83
+ def reset_state()
84
+ change_state STATE_READ_LENGTH
85
+ @item = FrameHeaderItem.new(0, FRAME_LEN_LENGTH)
86
+ @cont_len = 0
87
+ @read_bytes = 0
88
+ @tmp_buf.reset
89
+ @type = nil
90
+ @flags = 0
91
+ @stream_id = 0
92
+ @payload_len = 0
93
+ end
94
+
95
+ def bytes_received(buf)
96
+ suspend = false
97
+
98
+ @pos = 0
99
+ if @server_mode && !@preface_read
100
+ len = CONNECTION_PREFACE.length - @tmp_buf.length
101
+ if len > buf.length
102
+ len = buf.length
103
+ end
104
+ @tmp_buf.put(buf, @pos, len)
105
+ @pos += len
106
+ if @tmp_buf.length == CONNECTION_PREFACE.length
107
+ @tmp_buf.length.times do |i|
108
+ if CONNECTION_PREFACE[i] != @tmp_buf.buf[i]
109
+ raise ProtocolException.new "Invalid connection preface: #{@tmp_buf.bytes[0, @tmp_buf.length]}"
110
+ end
111
+ end
112
+ pkt = @pkt_store.rent(H2Type::PREFACE)
113
+ pkt.new_data_accessor().put_bytes(@tmp_buf.buf, 0, @tmp_buf.length)
114
+ nstat = @cmd_unpacker.packet_received(pkt)
115
+ @pkt_store.Return(pkt)
116
+ if nstat != NextSocketAction::CONTINUE
117
+ return nstat
118
+ end
119
+
120
+ BayLog.debug("h2: Connection preface OK")
121
+ @preface_read = true
122
+ @tmp_buf.reset()
123
+ end
124
+ end
125
+
126
+ while @state != STATE_END && pos < buf.length
127
+ case @state
128
+ when STATE_READ_LENGTH
129
+ if read_header_item(buf)
130
+ @payload_len = ((@item.get(@tmp_buf, 0) & 0xFF) << 16 |
131
+ (@item.get(@tmp_buf, 1) & 0xFF) << 8 |
132
+ (@item.get(@tmp_buf, 2) & 0xFF))
133
+ @item = FrameHeaderItem.new(@tmp_buf.length, FRAME_LEN_TYPE)
134
+ change_state STATE_READ_TYPE
135
+ end
136
+
137
+ when STATE_READ_TYPE
138
+ if read_header_item(buf)
139
+ @type = @item.get(@tmp_buf, 0)
140
+ @item = FrameHeaderItem.new(@tmp_buf.length, FRAME_LEN_FLAGS)
141
+ change_state STATE_READ_FLAGS
142
+ end
143
+
144
+ when STATE_READ_FLAGS
145
+ if read_header_item(buf)
146
+ @flags = @item.get(@tmp_buf, 0)
147
+ @item = FrameHeaderItem.new(@tmp_buf.length, FRAME_LEN_STREAM_IDENTIFIER)
148
+ change_state STATE_READ_STREAM_IDENTIFIER
149
+ end
150
+
151
+ when STATE_READ_STREAM_IDENTIFIER
152
+ if read_header_item(buf)
153
+ @stream_id =
154
+ ((@item.get(@tmp_buf, 0) & 0x7F) << 24) |
155
+ (@item.get(@tmp_buf, 1) << 16) |
156
+ (@item.get(@tmp_buf, 2) << 8) |
157
+ @item.get(@tmp_buf, 3)
158
+
159
+ @item = FrameHeaderItem.new(@tmp_buf.length, @payload_len)
160
+ change_state STATE_READ_FLAME_PAYLOAD
161
+ end
162
+
163
+ when STATE_READ_FLAME_PAYLOAD
164
+ if read_header_item(buf)
165
+ change_state STATE_END
166
+ end
167
+
168
+ else
169
+ raise RuntimeError.new "Illegal State"
170
+
171
+ end
172
+
173
+ if @state == STATE_END
174
+ pkt = @pkt_store.rent(@type)
175
+ pkt.stream_id = @stream_id
176
+ pkt.flags = H2Flags.new(@flags)
177
+ pkt.new_header_accessor().put_bytes(@tmp_buf.buf, 0, H2Packet::FRAME_HEADER_LEN)
178
+ pkt.new_data_accessor().put_bytes(@tmp_buf.buf, H2Packet::FRAME_HEADER_LEN, @tmp_buf.length - H2Packet::FRAME_HEADER_LEN)
179
+
180
+ begin
181
+ next_act = @cmd_unpacker.packet_received(pkt)
182
+ ensure
183
+ @pkt_store.Return(pkt)
184
+ reset_state()
185
+ end
186
+
187
+ if next_act == NextSocketAction::SUSPEND
188
+ suspend = true
189
+ elsif next_act != NextSocketAction::CONTINUE
190
+ return next_act
191
+ end
192
+ end
193
+ end
194
+
195
+ if suspend
196
+ return NextSocketAction::SUSPEND
197
+ else
198
+ return NextSocketAction::CONTINUE
199
+ end
200
+ end
201
+
202
+ private
203
+ def read_header_item(buf)
204
+ len = @item.len - @item.pos
205
+ if buf.length - @pos < len
206
+ len = buf.length - @pos
207
+ end
208
+ @tmp_buf.put(buf, @pos, len)
209
+ @pos += len
210
+ @item.pos += len
211
+
212
+ return @item.pos == @item.len
213
+ end
214
+
215
+ def change_state new_state
216
+ @state = new_state
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
222
+ end
223
+ end
224
+
@@ -0,0 +1,58 @@
1
+ require 'baykit/bayserver/protocol/protocol_handler'
2
+ require 'baykit/bayserver/protocol/packet_store'
3
+ require 'baykit/bayserver/util/headers'
4
+ require 'baykit/bayserver/docker/http/h2/command/package'
5
+ require 'baykit/bayserver/docker/http/h2/h2_packet'
6
+
7
+ module Baykit
8
+ module BayServer
9
+ module Docker
10
+ module Http
11
+ module H2
12
+ class H2ProtocolHandler < Baykit::BayServer::Protocol::ProtocolHandler
13
+ include Baykit::BayServer::Docker::Http::H2::H2CommandHandler # implements
14
+
15
+ include Baykit::BayServer::Agent
16
+ include Baykit::BayServer::Protocol
17
+ include Baykit::BayServer::Util
18
+ include Baykit::BayServer::Docker::Http::H2::Command
19
+ include Baykit::BayServer::Docker::Http::H2
20
+
21
+ CTL_STREAM_ID = 0
22
+
23
+ attr :req_header_tbl
24
+ attr :res_header_tbl
25
+
26
+ def initialize(pkt_store, svr_mode)
27
+ @command_unpacker = H2CommandUnPacker.new(self)
28
+ @packet_unpacker = H2PacketUnPacker.new(@command_unpacker, pkt_store, svr_mode)
29
+ @packet_packer = PacketPacker.new()
30
+ @command_packer = CommandPacker.new(@packet_packer, pkt_store)
31
+ @server_mode = svr_mode
32
+ @req_header_tbl = HeaderTable.create_dynamic_table()
33
+ @res_header_tbl = HeaderTable.create_dynamic_table()
34
+ end
35
+
36
+ ######################################################
37
+ # Implements ProtocolHandler
38
+ ######################################################
39
+
40
+ def max_req_packet_data_size
41
+ H2Packet::DEFAULT_PAYLOAD_MAXLEN
42
+ end
43
+
44
+ def max_res_packet_data_size
45
+ H2Packet::DEFAULT_PAYLOAD_MAXLEN
46
+ end
47
+
48
+ def protocol
49
+ return HtpPortDocker::H2_PROTO_NAME
50
+ end
51
+
52
+
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+ end
@@ -0,0 +1,42 @@
1
+ module Baykit
2
+ module BayServer
3
+ module Docker
4
+ module Http
5
+ module H2
6
+ class H2Settings
7
+
8
+ DEFAULT_HEADER_TABLE_SIZE = 4096
9
+ DEFAULT_ENABLE_PUSH = true
10
+ DEFAULT_MAX_CONCURRENT_STREAMS = -1
11
+ DEFAULT_MAX_WINDOW_SIZE = 65535
12
+ DEFAULT_MAX_FRAME_SIZE = 16384
13
+ DEFAULT_MAX_HEADER_LIST_SIZE = -1
14
+
15
+ attr_accessor :header_table_size
16
+ attr_accessor :enable_push
17
+ attr_accessor :max_concurrent_streams
18
+ attr_accessor :initial_window_size
19
+ attr_accessor :max_frame_size
20
+ attr_accessor :max_header_list_size
21
+
22
+ def initialize
23
+ reset
24
+ end
25
+
26
+ def reset
27
+ @header_table_size = DEFAULT_HEADER_TABLE_SIZE
28
+ @enable_push = DEFAULT_ENABLE_PUSH
29
+ @max_concurrent_streams = DEFAULT_MAX_CONCURRENT_STREAMS
30
+ @initial_window_size = DEFAULT_MAX_WINDOW_SIZE
31
+ @max_frame_size = DEFAULT_MAX_FRAME_SIZE
32
+ @max_header_list_size = DEFAULT_MAX_HEADER_LIST_SIZE
33
+ end
34
+
35
+ end
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+
42
+
@@ -0,0 +1,26 @@
1
+
2
+
3
+ module Baykit
4
+ module BayServer
5
+ module Docker
6
+ module Http
7
+ module H2
8
+ class H2Type
9
+ PREFACE = -1
10
+ DATA = 0
11
+ HEADERS = 1
12
+ PRIORITY = 2
13
+ RST_STREAM = 3
14
+ SETTINGS = 4
15
+ PUSH_PROMISE = 5
16
+ PING = 6
17
+ GOAWAY = 7
18
+ WINDOW_UPDATE = 8
19
+ CONTINUATION = 9
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
26
+
@@ -0,0 +1,142 @@
1
+ require 'baykit/bayserver/docker/warp/package'
2
+ require 'baykit/bayserver/protocol/protocol_exception'
3
+
4
+ module Baykit
5
+ module BayServer
6
+ module Docker
7
+ module Http
8
+ module H2
9
+ class H2WarpHandler < H2ProtocolHandler
10
+ include Baykit::BayServer::Docker::Warp::WarpHandler # implements
11
+
12
+ class WarpProtocolHandlerFactory
13
+ include Baykit::BayServer::Protocol::ProtocolHandlerFactory # implements
14
+
15
+ def create_protocol_handler(pkt_store)
16
+ return H2WarpHandler.new(pkt_store)
17
+ end
18
+ end
19
+
20
+ include Baykit::BayServer::Protocol
21
+ include Baykit::BayServer::Agent
22
+
23
+ attr :analyzer
24
+ attr :cur_stream_id
25
+
26
+ def initialize(pkt_store)
27
+ super(pkt_store, false)
28
+ end
29
+
30
+ ######################################################
31
+ # Implements Reusable
32
+ ######################################################
33
+
34
+ def reset()
35
+ super
36
+ @cur_stream_id = 1
37
+ end
38
+
39
+ ######################################################
40
+ # Implements WarpHandler
41
+ ######################################################
42
+ def next_warp_id
43
+ return H1WarpHandler::FIXED_WARP_ID
44
+ end
45
+
46
+ def new_warp_data(warp_id)
47
+ return WarpData.new(ship, warp_id)
48
+ end
49
+
50
+
51
+ def post_warp_headers(tur)
52
+ end
53
+
54
+ def send_req_contents(tur, buf, start, len)
55
+ end
56
+
57
+ def end_req_contents(tur)
58
+ end
59
+
60
+ def verify_protocol(proto)
61
+ end
62
+
63
+ ######################################################
64
+ # Implements H2CommandHandler
65
+ ######################################################
66
+ def handle_preface(cmd)
67
+ if BayLog.debug_mode?
68
+ BayLog.debug("#{ship} handle_preface: proto=#{cmd.protocol}")
69
+ end
70
+ raise Sink.new("Illegal State")
71
+ end
72
+
73
+ def handle_data(cmd)
74
+ if BayLog.debug_mode?
75
+ BayLog.debug("#{ship} handle_data: stm=#{cmd.stream_id} len=#{cmd.length}")
76
+ end
77
+ raise Sink.new("Illegal State")
78
+ end
79
+
80
+ def handle_headers(cmd)
81
+ if BayLog.debug_mode?
82
+ BayLog.debug("#{ship} handle_headers: stm=#{cmd.stream_id} dep=#{cmd.stream_dependency} weight=#{cmd.weight}")
83
+ end
84
+
85
+ raise Sink.new("Illegal State")
86
+ end
87
+
88
+ def handle_priority(cmd)
89
+ if BayLog.debug_mode?
90
+ BayLog.debug("#{@ship} handle_priority: stmid=#{cmd.stream_id} dep=#{cmd.stream_dependency} weight=#{cmd.weight}")
91
+ end
92
+ raise Sink.new("Illegal State")
93
+ end
94
+
95
+ def handle_settings(cmd)
96
+ if BayLog.debug_mode?
97
+ BayLog.debug("#{@ship} handle_settings: stmid=#{cmd.stream_id}")
98
+ end
99
+ raise Sink.new("Illegal State")
100
+ end
101
+
102
+ def handle_window_update(cmd)
103
+ if BayLog.debug_mode?
104
+ BayLog.debug("#{ship} handle_window_update: stmid=#{cmd.stream_id} size=#{cmd.window_size_increment}")
105
+ end
106
+ raise Sink.new("Illegal State")
107
+ end
108
+
109
+ def handle_go_away(cmd)
110
+ if BayLog.debug_mode?
111
+ BayLog.debug("#{ship} handle_go_away: last_stm=#{cmd.last_stream_id} code=#{cmd.error_code} " +
112
+ "desc=#{H2ErrorCode.msg.get_message(cmd.error_code.to_i)} " +
113
+ "debug=#{cmd.debug_data}")
114
+ end
115
+ return NextSocketAction::CLOSE
116
+ end
117
+
118
+ def handle_ping(cmd)
119
+ if BayLog.debug_mode?
120
+ BayLog.debug("#{ship} handle_ping: stm=#{cmd.stream_id}")
121
+ end
122
+ raise Sink.new("Illegal State")
123
+ end
124
+
125
+ def handle_rst_stream(cmd)
126
+ if BayLog.debug_mode?
127
+ BayLog.debug("#{ship} handle_rst_stream: stm=#{cmd.stream_id} code=#{cmd.error_code} " +
128
+ "desc=#{H2ErrorCode.msg.get_message(cmd.error_code.to_i)} ")
129
+ end
130
+ return NextSocketAction::CLOSE
131
+ end
132
+
133
+ def to_s
134
+ ship.to_s
135
+ end
136
+ end
137
+ end
138
+ end
139
+ end
140
+ end
141
+ end
142
+
@@ -0,0 +1,191 @@
1
+ module Baykit
2
+ module BayServer
3
+ module Docker
4
+ module Http
5
+ module H2
6
+ class HeaderBlock
7
+
8
+ INDEX = 1
9
+ OVERLOAD_KNOWN_HEADER = 2
10
+ NEW_HEADER = 3
11
+ KNOWN_HEADER = 4
12
+ UNKNOWN_HEADER = 5
13
+ UPDATE_DYNAMIC_TABLE_SIZE = 6
14
+
15
+ attr_accessor :op
16
+ attr_accessor :index
17
+ attr_accessor :name
18
+ attr_accessor :value
19
+ attr_accessor :size
20
+
21
+ def self.pack(blk, acc)
22
+ case blk.op
23
+ when INDEX
24
+ acc.put_hpack_int(blk.index, 7, 1)
25
+
26
+ when OVERLOAD_KNOWN_HEADER
27
+ raise RuntimeError.new("IllegalState")
28
+
29
+ when NEW_HEADER
30
+ raise RuntimeError.new("Illegal State")
31
+
32
+ when KNOWN_HEADER
33
+ acc.put_hpack_int(blk.index, 4, 0)
34
+ acc.put_hpack_string(blk.value, false)
35
+
36
+ when UNKNOWN_HEADER
37
+ acc.put_byte(0)
38
+ acc.put_hpack_string(blk.name, false)
39
+ acc.put_hpack_string(blk.value, false)
40
+
41
+ when UPDATE_DYNAMIC_TABLE_SIZE
42
+ raise RuntimeError.new("Illegal state")
43
+ end
44
+ end
45
+
46
+
47
+ def self.unpack(acc)
48
+ blk = HeaderBlock.new
49
+ index = acc.get_byte
50
+ is_index_header_field = (index & 0x80) != 0
51
+ if is_index_header_field
52
+ # index header field
53
+ # 0 1 2 3 4 5 6 7
54
+ # +---+---+---+---+---+---+---+---+
55
+ # | 1 | Index (7+) |
56
+ # +---+---------------------------+
57
+ blk.op = INDEX
58
+ blk.index = index & 0x7F
59
+ else
60
+ # literal header field
61
+ update_index = (index & 0x40) != 0
62
+ if update_index
63
+ index = index & 0x3F
64
+ overload_index = (index != 0)
65
+ if overload_index
66
+ if index == 0x3F
67
+ index = index + acc.get_hpack_int_rest
68
+ end
69
+ blk.op = OVERLOAD_KNOWN_HEADER
70
+ blk.index = index
71
+ # 0 1 2 3 4 5 6 7
72
+ # +---+---+---+---+---+---+---+---+
73
+ # | 0 | 1 | Index (6+) |
74
+ # +---+---+-----------------------+
75
+ # | H | Value Length (7+) |
76
+ # +---+---------------------------+
77
+ # | Value String (Length octets) |
78
+ # +-------------------------------+
79
+ blk.value = acc.get_hpack_string
80
+ else
81
+ # new header name
82
+ # 0 1 2 3 4 5 6 7
83
+ # +---+---+---+---+---+---+---+---+
84
+ # | 0 | 1 | 0 |
85
+ # +---+---+-----------------------+
86
+ # | H | Name Length (7+) |
87
+ # +---+---------------------------+
88
+ # | Name String (Length octets) |
89
+ # +---+---------------------------+
90
+ # | H | Value Length (7+) |
91
+ # +---+---------------------------+
92
+ # | Value String (Length octets) |
93
+ # +-------------------------------+
94
+ blk.op = NEW_HEADER
95
+ blk.name = acc.get_hpack_string
96
+ blk.value = acc.get_hpack_string
97
+ end
98
+ else
99
+ update_dynamic_table_size = (index & 0x20) != 0
100
+ if update_dynamic_table_size
101
+ # 0 1 2 3 4 5 6 7
102
+ # +---+---+---+---+---+---+---+---+
103
+ # | 0 | 0 | 1 | Max size (5+) |
104
+ # +---+---------------------------+
105
+ size = index & 0x1F
106
+ if size == 0x1F
107
+ size = size + acc.get_hpack_int_rest
108
+ end
109
+ blk.op = UPDATE_DYNAMIC_TABLE_SIZE
110
+ blk.size = size
111
+ else
112
+ # not update index
113
+ index = (index & 0xF)
114
+ if index != 0
115
+ # 0 1 2 3 4 5 6 7
116
+ # +---+---+---+---+---+---+---+---+
117
+ # | 0 | 0 | 0 | 0 | Index (4+) |
118
+ # +---+---+-----------------------+
119
+ # | H | Value Length (7+) |
120
+ # +---+---------------------------+
121
+ # | Value String (Length octets) |
122
+ # +-------------------------------+
123
+ #
124
+ # OR
125
+ #
126
+ # 0 1 2 3 4 5 6 7
127
+ # +---+---+---+---+---+---+---+---+
128
+ # | 0 | 0 | 0 | 1 | Index (4+) |
129
+ # +---+---+-----------------------+
130
+ # | H | Value Length (7+) |
131
+ # +---+---------------------------+
132
+ # | Value String (Length octets) |
133
+ # +-------------------------------+
134
+ if index == 0xF
135
+ index = index + acc.get_hpack_int_rest
136
+ end
137
+ blk.op = KNOWN_HEADER
138
+ blk.index = index
139
+ blk.value = acc.get_hpack_string
140
+ else
141
+ # literal header field
142
+ # 0 1 2 3 4 5 6 7
143
+ # +---+---+---+---+---+---+---+---+
144
+ # | 0 | 0 | 0 | 0 | 0 |
145
+ # +---+---+-----------------------+
146
+ # | H | Name Length (7+) |
147
+ # +---+---------------------------+
148
+ # | Name String (Length octets) |
149
+ # +---+---------------------------+
150
+ # | H | Value Length (7+) |
151
+ # +---+---------------------------+
152
+ # | Value String (Length octets) |
153
+ # +-------------------------------+
154
+ #
155
+ # OR
156
+ #
157
+ # 0 1 2 3 4 5 6 7
158
+ # +---+---+---+---+---+---+---+---+
159
+ # | 0 | 0 | 0 | 1 | 0 |
160
+ # +---+---+-----------------------+
161
+ # | H | Name Length (7+) |
162
+ # +---+---------------------------+
163
+ # | Name String (Length octets) |
164
+ # +---+---------------------------+
165
+ # | H | Value Length (7+) |
166
+ # +---+---------------------------+
167
+ # | Value String (Length octets) |
168
+ # +-------------------------------+
169
+ #
170
+ blk.op = UNKNOWN_HEADER
171
+ blk.name = acc.get_hpack_string
172
+ blk.value = acc.get_hpack_string
173
+ end
174
+ end
175
+ end
176
+ end
177
+
178
+ blk
179
+ end
180
+
181
+ def to_s
182
+ "#{op} index=#{index} name=#{name} value=#{value}"
183
+ end
184
+
185
+ end
186
+ end
187
+ end
188
+ end
189
+ end
190
+ end
191
+