http-2 1.1.2 → 1.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.
- checksums.yaml +4 -4
- data/lib/http/2/client.rb +1 -1
- data/lib/http/2/connection.rb +79 -62
- data/lib/http/2/extensions.rb +16 -10
- data/lib/http/2/flow_buffer.rb +12 -7
- data/lib/http/2/framer.rb +98 -98
- data/lib/http/2/header/compressor.rb +15 -4
- data/lib/http/2/header/decompressor.rb +11 -10
- data/lib/http/2/header/encoding_context.rb +18 -6
- data/lib/http/2/header/huffman.rb +6 -4
- data/lib/http/2/server.rb +12 -18
- data/lib/http/2/settings.rb +42 -0
- data/lib/http/2/stream.rb +19 -12
- data/lib/http/2/version.rb +1 -1
- data/sig/2.rbs +64 -15
- data/sig/connection.rbs +11 -9
- data/sig/flow_buffer.rbs +2 -2
- data/sig/frame_buffer.rbs +6 -2
- data/sig/framer.rbs +8 -4
- data/sig/header/compressor.rbs +1 -0
- data/sig/header/encoding_context.rbs +4 -0
- data/sig/header/huffman.rbs +2 -0
- data/sig/server.rbs +1 -1
- data/sig/stream.rbs +7 -8
- metadata +2 -1
data/lib/http/2/stream.rb
CHANGED
|
@@ -114,8 +114,10 @@ module HTTP2
|
|
|
114
114
|
def receive(frame)
|
|
115
115
|
transition(frame, false)
|
|
116
116
|
|
|
117
|
-
|
|
117
|
+
frame_type = frame[:type] #: Symbol
|
|
118
|
+
case frame_type
|
|
118
119
|
when :data
|
|
120
|
+
# @type var frame: data_frame
|
|
119
121
|
# 6.1. DATA
|
|
120
122
|
# If a DATA frame is received whose stream is not in "open" or
|
|
121
123
|
# "half closed (local)" state, the recipient MUST respond with a
|
|
@@ -129,6 +131,7 @@ module HTTP2
|
|
|
129
131
|
emit(:data, frame[:payload]) unless frame[:ignore]
|
|
130
132
|
calculate_window_update(@local_window_max_size)
|
|
131
133
|
when :headers
|
|
134
|
+
# @type var frame: headers_frame
|
|
132
135
|
stream_error(:stream_closed) if (@state == :closed && @closed != :local_rst) ||
|
|
133
136
|
@state == :remote_closed
|
|
134
137
|
@_method ||= frame[:method]
|
|
@@ -151,17 +154,18 @@ module HTTP2
|
|
|
151
154
|
stream_error(:stream_closed) if (@state == :closed && @closed != :local_rst) || @state == :remote_closed
|
|
152
155
|
stream_error(:protocol_error) if @received_data
|
|
153
156
|
when :priority
|
|
157
|
+
# @type var frame: priority_frame
|
|
154
158
|
process_priority(frame)
|
|
155
159
|
when :window_update
|
|
160
|
+
# @type var frame: window_update_frame
|
|
156
161
|
process_window_update(frame: frame)
|
|
157
162
|
when :altsvc
|
|
163
|
+
# @type var frame: origin_frame
|
|
158
164
|
# 4. The ALTSVC HTTP/2 Frame
|
|
159
165
|
# An ALTSVC frame on a
|
|
160
166
|
# stream other than stream 0 containing non-empty "Origin" information
|
|
161
167
|
# is invalid and MUST be ignored.
|
|
162
|
-
emit(
|
|
163
|
-
when :blocked
|
|
164
|
-
emit(frame[:type], frame)
|
|
168
|
+
emit(frame_type, frame) if !frame[:origin] || frame[:origin].empty?
|
|
165
169
|
end
|
|
166
170
|
|
|
167
171
|
complete_transition(frame)
|
|
@@ -199,11 +203,14 @@ module HTTP2
|
|
|
199
203
|
def send(frame)
|
|
200
204
|
case frame[:type]
|
|
201
205
|
when :data
|
|
206
|
+
# @type var frame: data_frame
|
|
202
207
|
# stream state management is maintained in send_data
|
|
203
208
|
return send_data(frame)
|
|
204
209
|
when :window_update
|
|
210
|
+
# @type var frame: window_update_frame
|
|
205
211
|
@local_window += frame[:increment]
|
|
206
212
|
when :priority
|
|
213
|
+
# @type var frame: priority_frame
|
|
207
214
|
process_priority(frame)
|
|
208
215
|
end
|
|
209
216
|
|
|
@@ -219,9 +226,8 @@ module HTTP2
|
|
|
219
226
|
# @param end_headers [Boolean] indicates that no more headers will be sent
|
|
220
227
|
# @param end_stream [Boolean] indicates that no payload will be sent
|
|
221
228
|
def headers(headers, end_headers: true, end_stream: false)
|
|
222
|
-
flags =
|
|
223
|
-
flags
|
|
224
|
-
flags << :end_stream if end_stream || @_method == "HEAD"
|
|
229
|
+
flags = end_headers ? END_HEADERS : 0
|
|
230
|
+
flags |= END_STREAM if end_stream || @_method == "HEAD"
|
|
225
231
|
|
|
226
232
|
send(type: :headers, flags: flags, payload: headers)
|
|
227
233
|
end
|
|
@@ -229,7 +235,7 @@ module HTTP2
|
|
|
229
235
|
def promise(headers, end_headers: true, &block)
|
|
230
236
|
raise ArgumentError, "must provide callback" unless block
|
|
231
237
|
|
|
232
|
-
flags = end_headers ?
|
|
238
|
+
flags = end_headers ? END_HEADERS : 0
|
|
233
239
|
emit(:promise, self, headers, flags, &block)
|
|
234
240
|
end
|
|
235
241
|
|
|
@@ -254,12 +260,12 @@ module HTTP2
|
|
|
254
260
|
|
|
255
261
|
if payload.bytesize > max_size
|
|
256
262
|
payload = chunk_data(payload, max_size) do |chunk|
|
|
257
|
-
send(type: :data, flags:
|
|
263
|
+
send(type: :data, flags: 0, payload: chunk)
|
|
258
264
|
end
|
|
259
265
|
end
|
|
260
266
|
|
|
261
|
-
flags =
|
|
262
|
-
flags
|
|
267
|
+
flags = 0
|
|
268
|
+
flags |= END_STREAM if end_stream
|
|
263
269
|
send(type: :data, flags: flags, payload: payload)
|
|
264
270
|
end
|
|
265
271
|
|
|
@@ -663,7 +669,8 @@ module HTTP2
|
|
|
663
669
|
def end_stream?(frame)
|
|
664
670
|
case frame[:type]
|
|
665
671
|
when :data, :headers, :continuation
|
|
666
|
-
frame
|
|
672
|
+
# @type var frame: data_frame | headers_frame | continuation_frame
|
|
673
|
+
frame[:flags] && frame[:flags].anybits?(END_STREAM)
|
|
667
674
|
else false
|
|
668
675
|
end
|
|
669
676
|
end
|
data/lib/http/2/version.rb
CHANGED
data/sig/2.rbs
CHANGED
|
@@ -36,49 +36,96 @@ module HTTP2
|
|
|
36
36
|
|
|
37
37
|
RESPONSE_MANDATORY_HEADERS: Array[String]
|
|
38
38
|
|
|
39
|
+
# Frame flags
|
|
40
|
+
END_STREAM: Integer
|
|
41
|
+
ACK: Integer
|
|
42
|
+
RESERVED: Integer
|
|
43
|
+
END_HEADERS: Integer
|
|
44
|
+
PADDED: Integer
|
|
45
|
+
PRIORITY: Integer
|
|
46
|
+
|
|
39
47
|
type header_pair = [string, string]
|
|
40
48
|
|
|
41
49
|
# # FRAMES
|
|
42
|
-
type frame_control_flags =
|
|
50
|
+
type frame_control_flags = Integer
|
|
51
|
+
|
|
52
|
+
type common_frame = { stream: Integer, flags: frame_control_flags, ?length: Integer, ?ignore: bool }
|
|
43
53
|
|
|
44
|
-
type
|
|
54
|
+
type connection_frame = settings_frame | ping_frame | goaway_frame | window_update_frame | altsvc_frame | origin_frame
|
|
45
55
|
|
|
46
56
|
# # HEADERS
|
|
47
|
-
type
|
|
48
|
-
type: :headers,
|
|
57
|
+
type headers_frame_props = {
|
|
58
|
+
type: :headers, payload: Enumerable[header_pair] | String,
|
|
49
59
|
?method: Symbol, ?trailer: Array[String], ?content_length: Integer, ?padding: Integer
|
|
50
60
|
}
|
|
61
|
+
type headers_frame = common_frame & headers_frame_props
|
|
62
|
+
|
|
63
|
+
type continuation_frame_props = headers_frame_props | { type: :continuation }
|
|
64
|
+
|
|
65
|
+
type continuation_frame = common_frame & continuation_frame_props
|
|
51
66
|
|
|
52
67
|
# # DATA
|
|
53
|
-
type
|
|
68
|
+
type data_frame_props = { type: :data, ?length: Integer, payload: String, ?padding: Integer }
|
|
69
|
+
|
|
70
|
+
type data_frame = common_frame & data_frame_props
|
|
54
71
|
|
|
55
72
|
# # PUSH_PROMISE
|
|
56
|
-
type
|
|
73
|
+
type push_promise_frame_props = { promise_stream: Integer, ?length: Integer, ?method: Symbol, ?trailer: Array[String], ?content_length: Integer, payload: Enumerable[header_pair] | String, ?padding: Integer }
|
|
74
|
+
|
|
75
|
+
type push_promise_frame = common_frame & push_promise_frame_props
|
|
57
76
|
|
|
58
77
|
# # SETTINGS
|
|
59
|
-
type
|
|
78
|
+
type settings_frame_props = { type: :settings, payload: (Enumerable[[Symbol | Integer, Integer]] | String) }
|
|
79
|
+
|
|
80
|
+
type settings_frame = common_frame & settings_frame_props
|
|
60
81
|
|
|
61
82
|
# # WINDOW_UPDATE
|
|
62
|
-
type
|
|
83
|
+
type window_update_frame_props = { type: :window_update, increment: Integer }
|
|
84
|
+
|
|
85
|
+
type window_update_frame = common_frame & window_update_frame_props
|
|
63
86
|
|
|
64
87
|
# # PRIORITY
|
|
65
|
-
type
|
|
88
|
+
type priority_frame_inner_props = { dependency: Integer, exclusive: bool, weight: Integer }
|
|
89
|
+
|
|
90
|
+
type priority_frame_props = { type: :priority } & priority_frame_inner_props
|
|
91
|
+
|
|
92
|
+
type priority_frame = common_frame & priority_frame_props
|
|
66
93
|
|
|
67
94
|
# # ALTSVC
|
|
68
|
-
type
|
|
95
|
+
type altsvc_frame_props = { type: :altsvc, max_age: Integer, port: Integer, proto: String, host: String }
|
|
96
|
+
|
|
97
|
+
type altsvc_frame = common_frame & altsvc_frame_props
|
|
69
98
|
|
|
70
99
|
# # ORIGIN
|
|
71
|
-
type
|
|
100
|
+
type origin_frame_props = { type: :origin, payload: Array[String] }
|
|
101
|
+
|
|
102
|
+
type origin_frame = common_frame & origin_frame_props
|
|
72
103
|
|
|
73
104
|
# # PING
|
|
74
|
-
type
|
|
105
|
+
type ping_frame_props = { type: :ping, payload: String }
|
|
106
|
+
|
|
107
|
+
type ping_frame = common_frame & ping_frame_props
|
|
75
108
|
|
|
76
109
|
# # GOAWAY
|
|
77
|
-
type
|
|
110
|
+
type goaway_frame_props = { type: :goaway, last_stream: Integer, error: (Symbol | Integer)? }
|
|
111
|
+
|
|
112
|
+
type goaway_frame = common_frame & goaway_frame_props
|
|
78
113
|
|
|
79
|
-
#
|
|
114
|
+
# # RST_STREAM
|
|
115
|
+
type rst_stream_frame_props = { type: :rst_stream, error: (Symbol | Integer)? }
|
|
116
|
+
|
|
117
|
+
type rst_stream_frame = common_frame & rst_stream_frame_props
|
|
118
|
+
|
|
119
|
+
# type frame = headers_frame | continuation_frame | push_promise_frame | data_frame |
|
|
80
120
|
# settings_frame | window_update_frame | priority_frame | altsvc_frame |
|
|
81
|
-
# origin_frame | ping_frame | goaway_frame
|
|
121
|
+
# origin_frame | ping_frame | goaway_frame | rst_stream_frame
|
|
122
|
+
|
|
123
|
+
# type connection_frame_props = rst_stream_frame_props | ping_frame_props | goaway_frame_props
|
|
124
|
+
# | window_update_frame_props | settings_frame_props
|
|
125
|
+
|
|
126
|
+
# type stream_frame_props = headers_frame_props | continuation_frame_props | push_promise_frame_props
|
|
127
|
+
# | data_frame_props | rst_stream_frame_props | priority_frame_props
|
|
128
|
+
# | window_update_frame_props | origin_frame_props | altsvc_frame_props
|
|
82
129
|
|
|
83
130
|
type frame_key = :type | :flags | :stream | :padding | :ignore |
|
|
84
131
|
# headers
|
|
@@ -109,4 +156,6 @@ module HTTP2
|
|
|
109
156
|
nil
|
|
110
157
|
|
|
111
158
|
type frame = Hash[frame_key, frame_value]
|
|
159
|
+
type connection_frame_props = Hash[frame_key, frame_value]
|
|
160
|
+
type stream_frame_props = Hash[frame_key, frame_value]
|
|
112
161
|
end
|
data/sig/connection.rbs
CHANGED
|
@@ -33,6 +33,7 @@ module HTTP2
|
|
|
33
33
|
|
|
34
34
|
@streams: Hash[Integer, Stream]
|
|
35
35
|
@streams_recently_closed: Hash[Integer, Numeric]
|
|
36
|
+
@oldest_stream_recently_closed: Numeric
|
|
36
37
|
|
|
37
38
|
@framer: Framer
|
|
38
39
|
|
|
@@ -50,6 +51,7 @@ module HTTP2
|
|
|
50
51
|
|
|
51
52
|
@recv_buffer: String
|
|
52
53
|
@continuation: Array[frame]
|
|
54
|
+
@continuation_size: Integer
|
|
53
55
|
|
|
54
56
|
@h2c_upgrade: Symbol?
|
|
55
57
|
@closed_since: Float?
|
|
@@ -68,39 +70,39 @@ module HTTP2
|
|
|
68
70
|
|
|
69
71
|
def settings: (settings_enum payload) -> void
|
|
70
72
|
|
|
71
|
-
def receive: (
|
|
73
|
+
def receive: (String data) -> void
|
|
72
74
|
alias << receive
|
|
73
75
|
|
|
74
76
|
def initialize: (?connection_opts) -> void
|
|
75
77
|
|
|
76
78
|
private
|
|
77
79
|
|
|
78
|
-
def send: (
|
|
80
|
+
def send: (connection_frame_props | stream_frame_props frame) -> void
|
|
79
81
|
|
|
80
82
|
def encode: (frame frame) -> void
|
|
81
83
|
|
|
82
84
|
def connection_frame?: (frame) -> bool
|
|
83
85
|
|
|
84
|
-
def connection_management: (frame) -> void
|
|
86
|
+
def connection_management: (connection_frame frame) -> void
|
|
85
87
|
|
|
86
88
|
def ping_management: (frame) -> void
|
|
87
89
|
|
|
88
90
|
def validate_settings: (role_type, settings_enum) -> void
|
|
89
91
|
|
|
90
|
-
def connection_settings: (
|
|
92
|
+
def connection_settings: (settings_frame) -> void
|
|
91
93
|
|
|
92
|
-
def decode_headers: (
|
|
94
|
+
def decode_headers: (headers_frame | push_promise_frame) -> void
|
|
93
95
|
|
|
94
|
-
def encode_headers: (
|
|
96
|
+
def encode_headers: (headers_frame | push_promise_frame) -> void
|
|
95
97
|
|
|
96
98
|
def activate_stream: (id: Integer, **untyped) -> Stream
|
|
97
99
|
|
|
98
100
|
def verify_stream_order: (Integer id) -> void
|
|
99
101
|
|
|
100
|
-
def verify_pseudo_headers: (
|
|
102
|
+
def verify_pseudo_headers: (headers_frame | push_promise_frame) -> void
|
|
101
103
|
|
|
102
|
-
def _verify_pseudo_headers: (
|
|
104
|
+
def _verify_pseudo_headers: (headers_frame | push_promise_frame, Array[String]) -> void
|
|
103
105
|
|
|
104
106
|
def connection_error: (?Symbol error, ?msg: String?, ?e: StandardError?) -> void
|
|
105
107
|
end
|
|
106
|
-
end
|
|
108
|
+
end
|
data/sig/flow_buffer.rbs
CHANGED
|
@@ -14,9 +14,9 @@ module HTTP2
|
|
|
14
14
|
|
|
15
15
|
def calculate_window_update: (Integer) -> void
|
|
16
16
|
|
|
17
|
-
def send_data: (?
|
|
17
|
+
def send_data: (?data_frame_props? frame, ?bool encode) -> void
|
|
18
18
|
|
|
19
|
-
def send_frame: (
|
|
19
|
+
def send_frame: (data_frame_props frame, bool encode) -> void
|
|
20
20
|
|
|
21
21
|
def process_window_update: (frame: window_update_frame, ?encode: bool) -> void
|
|
22
22
|
end
|
data/sig/frame_buffer.rbs
CHANGED
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
module HTTP2
|
|
2
2
|
class FrameBuffer
|
|
3
|
+
include BufferUtils
|
|
4
|
+
|
|
3
5
|
attr_reader bytesize: Integer
|
|
4
6
|
|
|
5
7
|
@buffer: Array[data_frame]
|
|
6
8
|
|
|
7
|
-
def
|
|
9
|
+
def clear: () -> void
|
|
10
|
+
|
|
11
|
+
def <<: (data_frame_props frame) -> void
|
|
8
12
|
|
|
9
13
|
def empty?: () -> bool
|
|
10
14
|
|
|
11
|
-
def retrieve: (Integer) ->
|
|
15
|
+
def retrieve: (Integer) -> data_frame_props?
|
|
12
16
|
end
|
|
13
17
|
end
|
data/sig/framer.rbs
CHANGED
|
@@ -20,7 +20,9 @@ module HTTP2
|
|
|
20
20
|
|
|
21
21
|
DEFINED_SETTINGS: Hash[Symbol, Integer]
|
|
22
22
|
|
|
23
|
-
|
|
23
|
+
DEFINED_SETTINGS_BY_ID: Hash[Integer, Symbol]
|
|
24
|
+
|
|
25
|
+
DEFINED_ERRORS: Array[Symbol]
|
|
24
26
|
|
|
25
27
|
RBIT: Integer
|
|
26
28
|
RBYTE: Integer
|
|
@@ -29,6 +31,8 @@ module HTTP2
|
|
|
29
31
|
UINT16: String
|
|
30
32
|
UINT8: String
|
|
31
33
|
HEADERPACK: String
|
|
34
|
+
PRIORITYPACK: String
|
|
35
|
+
ALTSVCPACK: String
|
|
32
36
|
FRAME_LENGTH_HISHIFT: Integer
|
|
33
37
|
FRAME_LENGTH_LOMASK: Integer
|
|
34
38
|
|
|
@@ -41,19 +45,19 @@ module HTTP2
|
|
|
41
45
|
|
|
42
46
|
def common_header: (frame, buffer: String) -> String
|
|
43
47
|
|
|
44
|
-
def read_common_header: (String buf) ->
|
|
48
|
+
def read_common_header: (String buf) -> (common_frame | { length: Integer })
|
|
45
49
|
|
|
46
50
|
def read_common_frame: (String) -> frame
|
|
47
51
|
|
|
48
52
|
def generate: (frame) -> String
|
|
49
53
|
|
|
50
|
-
def parse: (String) -> frame?
|
|
54
|
+
def parse: (String) -> (frame | { length: Integer })?
|
|
51
55
|
|
|
52
56
|
private
|
|
53
57
|
|
|
54
58
|
def initialize: (?Integer local_max_frame_size, ?Integer remote_max_frame_size) -> untyped
|
|
55
59
|
|
|
56
|
-
def pack_error: (
|
|
60
|
+
def pack_error: (Symbol | Integer error, buffer: String) -> String
|
|
57
61
|
|
|
58
62
|
def unpack_error: (Integer) -> (Symbol | Integer)
|
|
59
63
|
end
|
data/sig/header/compressor.rbs
CHANGED
data/sig/header/huffman.rbs
CHANGED
data/sig/server.rbs
CHANGED
|
@@ -7,6 +7,6 @@ module HTTP2
|
|
|
7
7
|
|
|
8
8
|
private
|
|
9
9
|
|
|
10
|
-
def promise: (Stream parent, Enumerable[header_pair] headers,
|
|
10
|
+
def promise: (Stream parent, Enumerable[header_pair] headers, frame_control_flags flags) { (Stream) -> void } -> void
|
|
11
11
|
end
|
|
12
12
|
end
|
data/sig/stream.rbs
CHANGED
|
@@ -37,7 +37,7 @@ module HTTP2
|
|
|
37
37
|
|
|
38
38
|
def calculate_content_length: (Integer?) -> void
|
|
39
39
|
|
|
40
|
-
def send: (
|
|
40
|
+
def send: (stream_frame_props frame) -> void
|
|
41
41
|
|
|
42
42
|
def headers: (Enumerable[header_pair] headers, ?end_headers: bool, ?end_stream: bool) -> void
|
|
43
43
|
|
|
@@ -70,7 +70,7 @@ module HTTP2
|
|
|
70
70
|
?state: Symbol
|
|
71
71
|
) -> untyped
|
|
72
72
|
|
|
73
|
-
def transition: (frame, bool sending) -> void
|
|
73
|
+
def transition: (stream_frame_props frame, bool sending) -> void
|
|
74
74
|
|
|
75
75
|
def event: (Symbol newstate) -> void
|
|
76
76
|
|
|
@@ -80,15 +80,14 @@ module HTTP2
|
|
|
80
80
|
|
|
81
81
|
def complete_transition: (frame) -> void
|
|
82
82
|
|
|
83
|
-
def process_priority: (
|
|
83
|
+
def process_priority: (priority_frame_inner_props frame) -> void
|
|
84
84
|
|
|
85
|
-
def end_stream?: (
|
|
85
|
+
def end_stream?: (stream_frame_props frame) -> boolish
|
|
86
86
|
|
|
87
|
-
def stream_error: (Symbol error, ?msg: String?) -> void
|
|
88
|
-
| () -> void
|
|
87
|
+
def stream_error: (?Symbol error, ?msg: String?) -> void
|
|
89
88
|
|
|
90
89
|
alias error stream_error
|
|
91
90
|
|
|
92
|
-
def manage_state: (frame) { () -> void } -> void
|
|
91
|
+
def manage_state: (stream_frame_props frame) { () -> void } -> void
|
|
93
92
|
end
|
|
94
|
-
end
|
|
93
|
+
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: http-2
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.
|
|
4
|
+
version: 1.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tiago Cardoso
|
|
@@ -36,6 +36,7 @@ files:
|
|
|
36
36
|
- lib/http/2/header/huffman.rb
|
|
37
37
|
- lib/http/2/header/huffman_statemachine.rb
|
|
38
38
|
- lib/http/2/server.rb
|
|
39
|
+
- lib/http/2/settings.rb
|
|
39
40
|
- lib/http/2/stream.rb
|
|
40
41
|
- lib/http/2/version.rb
|
|
41
42
|
- sig/2.rbs
|