http-2 0.8.2 → 0.8.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -0
- data/.rubocop.yml +41 -2
- data/.rubocop_todo.yml +85 -12
- data/Gemfile +1 -2
- data/Guardfile +19 -0
- data/Guardfile.h2spec +12 -0
- data/README.md +18 -9
- data/Rakefile +39 -1
- data/example/Gemfile +3 -0
- data/example/README.md +4 -0
- data/example/client.rb +10 -9
- data/example/helper.rb +1 -1
- data/example/keys/server.crt +20 -0
- data/example/keys/server.key +27 -0
- data/example/server.rb +48 -4
- data/example/upgrade_server.rb +20 -10
- data/lib/http/2/buffer.rb +42 -14
- data/lib/http/2/compressor.rb +2 -2
- data/lib/http/2/connection.rb +38 -16
- data/lib/http/2/emitter.rb +1 -1
- data/lib/http/2/framer.rb +12 -7
- data/lib/http/2/server.rb +2 -1
- data/lib/http/2/stream.rb +25 -11
- data/lib/http/2/version.rb +1 -1
- data/lib/tasks/generate_huffman_table.rb +3 -3
- data/spec/client_spec.rb +3 -3
- data/spec/connection_spec.rb +0 -1
- data/spec/h2spec/h2spec.darwin +0 -0
- data/spec/h2spec/output/non_secure.txt +317 -0
- data/spec/helper.rb +1 -1
- data/spec/hpack_test_spec.rb +1 -1
- data/spec/stream_spec.rb +22 -1
- data/spec/support/deep_dup.rb +55 -0
- data/spec/support/duplicable.rb +98 -0
- metadata +16 -5
- data/example/keys/mycert.pem +0 -23
- data/example/keys/mykey.pem +0 -27
data/lib/http/2/framer.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
module HTTP2
|
2
2
|
# Performs encoding, decoding, and validation of binary HTTP/2 frames.
|
3
3
|
#
|
4
|
+
# rubocop:disable ClassLength
|
4
5
|
class Framer
|
5
6
|
include Error
|
6
7
|
|
@@ -215,7 +216,7 @@ module HTTP2
|
|
215
216
|
length += 4
|
216
217
|
|
217
218
|
when :settings
|
218
|
-
if frame[:stream]
|
219
|
+
if (frame[:stream]).nonzero?
|
219
220
|
fail CompressionError, "Invalid stream ID (#{frame[:stream]})"
|
220
221
|
end
|
221
222
|
|
@@ -268,7 +269,8 @@ module HTTP2
|
|
268
269
|
length += 6
|
269
270
|
if frame[:proto]
|
270
271
|
fail CompressionError, 'Proto too long' if frame[:proto].bytesize > 255
|
271
|
-
bytes << [frame[:proto].bytesize].pack(UINT8)
|
272
|
+
bytes << [frame[:proto].bytesize].pack(UINT8)
|
273
|
+
bytes << frame[:proto].force_encoding(Encoding::BINARY)
|
272
274
|
length += 1 + frame[:proto].bytesize
|
273
275
|
else
|
274
276
|
bytes << [0].pack(UINT8)
|
@@ -276,7 +278,8 @@ module HTTP2
|
|
276
278
|
end
|
277
279
|
if frame[:host]
|
278
280
|
fail CompressionError, 'Host too long' if frame[:host].bytesize > 255
|
279
|
-
bytes << [frame[:host].bytesize].pack(UINT8)
|
281
|
+
bytes << [frame[:host].bytesize].pack(UINT8)
|
282
|
+
bytes << frame[:host].force_encoding(Encoding::BINARY)
|
280
283
|
length += 1 + frame[:host].bytesize
|
281
284
|
else
|
282
285
|
bytes << [0].pack(UINT8)
|
@@ -325,6 +328,8 @@ module HTTP2
|
|
325
328
|
frame = read_common_header(buf)
|
326
329
|
return nil if buf.size < 9 + frame[:length]
|
327
330
|
|
331
|
+
fail ProtocolError, 'payload too large' if frame[:length] > DEFAULT_MAX_FRAME_SIZE
|
332
|
+
|
328
333
|
buf.read(9)
|
329
334
|
payload = buf.read(frame[:length])
|
330
335
|
|
@@ -354,14 +359,14 @@ module HTTP2
|
|
354
359
|
if frame[:flags].include? :priority
|
355
360
|
e_sd = payload.read_uint32
|
356
361
|
frame[:stream_dependency] = e_sd & RBIT
|
357
|
-
frame[:exclusive] = (e_sd & EBIT) != 0
|
362
|
+
frame[:exclusive] = (e_sd & EBIT) != 0 # rubocop:disable Style/NumericPredicate
|
358
363
|
frame[:weight] = payload.getbyte + 1
|
359
364
|
end
|
360
365
|
frame[:payload] = payload.read(frame[:length])
|
361
366
|
when :priority
|
362
367
|
e_sd = payload.read_uint32
|
363
368
|
frame[:stream_dependency] = e_sd & RBIT
|
364
|
-
frame[:exclusive] = (e_sd & EBIT) != 0
|
369
|
+
frame[:exclusive] = (e_sd & EBIT) != 0 # rubocop:disable Style/NumericPredicate
|
365
370
|
frame[:weight] = payload.getbyte + 1
|
366
371
|
when :rst_stream
|
367
372
|
frame[:error] = unpack_error payload.read_uint32
|
@@ -370,11 +375,11 @@ module HTTP2
|
|
370
375
|
# NOTE: frame[:length] might not match the number of frame[:payload]
|
371
376
|
# because unknown extensions are ignored.
|
372
377
|
frame[:payload] = []
|
373
|
-
unless frame[:length] % 6
|
378
|
+
unless (frame[:length] % 6).zero?
|
374
379
|
fail ProtocolError, 'Invalid settings payload length'
|
375
380
|
end
|
376
381
|
|
377
|
-
if frame[:stream]
|
382
|
+
if (frame[:stream]).nonzero?
|
378
383
|
fail ProtocolError, "Invalid stream ID (#{frame[:stream]})"
|
379
384
|
end
|
380
385
|
|
data/lib/http/2/server.rb
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
require 'base64'
|
1
2
|
module HTTP2
|
2
3
|
# HTTP 2.0 server connection class that implements appropriate header
|
3
4
|
# compression / decompression algorithms and stream management logic.
|
@@ -71,7 +72,7 @@ module HTTP2
|
|
71
72
|
receive(CONNECTION_PREFACE_MAGIC)
|
72
73
|
|
73
74
|
# Process received HTTP2-Settings payload
|
74
|
-
buf = HTTP2::Buffer.new Base64.urlsafe_decode64(settings)
|
75
|
+
buf = HTTP2::Buffer.new Base64.urlsafe_decode64(settings.to_s)
|
75
76
|
header = @framer.common_header(
|
76
77
|
length: buf.bytesize,
|
77
78
|
type: :settings,
|
data/lib/http/2/stream.rb
CHANGED
@@ -54,7 +54,7 @@ module HTTP2
|
|
54
54
|
# Size of current stream flow control window.
|
55
55
|
attr_reader :local_window
|
56
56
|
attr_reader :remote_window
|
57
|
-
|
57
|
+
alias window local_window
|
58
58
|
|
59
59
|
# Reason why connection was closed.
|
60
60
|
attr_reader :closed
|
@@ -117,7 +117,7 @@ module HTTP2
|
|
117
117
|
|
118
118
|
complete_transition(frame)
|
119
119
|
end
|
120
|
-
|
120
|
+
alias << receive
|
121
121
|
|
122
122
|
# Processes outgoing HTTP 2.0 frames. Data frames may be automatically
|
123
123
|
# split and buffered based on maximum frame size and current stream flow
|
@@ -182,9 +182,11 @@ module HTTP2
|
|
182
182
|
# Split data according to each frame is smaller enough
|
183
183
|
# TODO: consider padding?
|
184
184
|
max_size = @connection.remote_settings[:settings_max_frame_size]
|
185
|
-
|
186
|
-
|
187
|
-
|
185
|
+
|
186
|
+
if payload.bytesize > max_size
|
187
|
+
payload = chunk_data(payload, max_size) do |chunk|
|
188
|
+
send(type: :data, flags: [], payload: chunk)
|
189
|
+
end
|
188
190
|
end
|
189
191
|
|
190
192
|
flags = []
|
@@ -192,6 +194,18 @@ module HTTP2
|
|
192
194
|
send(type: :data, flags: flags, payload: payload)
|
193
195
|
end
|
194
196
|
|
197
|
+
# Chunk data into max_size, yield each chunk, then return final chunk
|
198
|
+
#
|
199
|
+
def chunk_data(payload, max_size)
|
200
|
+
total = payload.bytesize
|
201
|
+
cursor = 0
|
202
|
+
while (total - cursor) > max_size
|
203
|
+
yield payload.byteslice(cursor, max_size)
|
204
|
+
cursor += max_size
|
205
|
+
end
|
206
|
+
payload.byteslice(cursor, total - cursor)
|
207
|
+
end
|
208
|
+
|
195
209
|
# Sends a RST_STREAM frame which closes current stream - this does not
|
196
210
|
# close the underlying connection.
|
197
211
|
#
|
@@ -320,14 +334,14 @@ module HTTP2
|
|
320
334
|
# WINDOW_UPDATE on a stream in this state MUST be treated as a
|
321
335
|
# connection error (Section 5.4.1) of type PROTOCOL_ERROR.
|
322
336
|
when :reserved_local
|
323
|
-
if sending
|
324
|
-
|
337
|
+
@state = if sending
|
338
|
+
case frame[:type]
|
325
339
|
when :headers then event(:half_closed_remote)
|
326
340
|
when :rst_stream then event(:local_rst)
|
327
341
|
else stream_error
|
328
342
|
end
|
329
343
|
else
|
330
|
-
|
344
|
+
case frame[:type]
|
331
345
|
when :rst_stream then event(:remote_rst)
|
332
346
|
when :priority, :window_update then @state
|
333
347
|
else stream_error
|
@@ -349,14 +363,14 @@ module HTTP2
|
|
349
363
|
# PRIORITY on a stream in this state MUST be treated as a connection
|
350
364
|
# error (Section 5.4.1) of type PROTOCOL_ERROR.
|
351
365
|
when :reserved_remote
|
352
|
-
if sending
|
353
|
-
|
366
|
+
@state = if sending
|
367
|
+
case frame[:type]
|
354
368
|
when :rst_stream then event(:local_rst)
|
355
369
|
when :priority, :window_update then @state
|
356
370
|
else stream_error
|
357
371
|
end
|
358
372
|
else
|
359
|
-
|
373
|
+
case frame[:type]
|
360
374
|
when :headers then event(:half_closed_local)
|
361
375
|
when :rst_stream then event(:remote_rst)
|
362
376
|
else stream_error
|
data/lib/http/2/version.rb
CHANGED
@@ -25,10 +25,10 @@ module HuffmanTable
|
|
25
25
|
|
26
26
|
def add(code, len, chr)
|
27
27
|
self.final = true if chr == EOS && @depth <= 7
|
28
|
-
if len
|
28
|
+
if len.zero?
|
29
29
|
@emit = chr
|
30
30
|
else
|
31
|
-
bit = (code & (1 << (len - 1)))
|
31
|
+
bit = (code & (1 << (len - 1))).zero? ? 0 : 1
|
32
32
|
node = @next[bit] ||= Node.new(@depth + 1)
|
33
33
|
node.add(code, len - 1, chr)
|
34
34
|
end
|
@@ -68,7 +68,7 @@ module HuffmanTable
|
|
68
68
|
n = node
|
69
69
|
emit = ''
|
70
70
|
(BITS_AT_ONCE - 1).downto(0) do |i|
|
71
|
-
bit = (input & (1 << i))
|
71
|
+
bit = (input & (1 << i)).zero? ? 0 : 1
|
72
72
|
n = n.next[bit]
|
73
73
|
next unless n.emit
|
74
74
|
if n.emit == EOS
|
data/spec/client_spec.rb
CHANGED
@@ -56,10 +56,10 @@ RSpec.describe HTTP2::Client do
|
|
56
56
|
it 'should raise error on PUSH_PROMISE against non-idle stream' do
|
57
57
|
expect do
|
58
58
|
s = @client.new_stream
|
59
|
-
s.send HEADERS
|
59
|
+
s.send HEADERS.dup
|
60
60
|
|
61
|
-
@client << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
62
|
-
@client << set_stream_id(f.generate(PUSH_PROMISE), s.id)
|
61
|
+
@client << set_stream_id(f.generate(PUSH_PROMISE.dup), s.id)
|
62
|
+
@client << set_stream_id(f.generate(PUSH_PROMISE.dup), s.id)
|
63
63
|
end.to raise_error(ProtocolError)
|
64
64
|
end
|
65
65
|
|
data/spec/connection_spec.rb
CHANGED
Binary file
|
@@ -0,0 +1,317 @@
|
|
1
|
+
3.5. HTTP/2 Connection Preface
|
2
|
+
Sends invalid connection preface
|
3
|
✓ Sends invalid connection preface
|
4
|
+
|
5
|
+
4.2. Frame Size
|
6
|
+
Sends large size frame that exceeds the SETTINGS_MAX_FRAME_SIZE
|
1
7
|
✓ Sends large size frame that exceeds the SETTINGS_MAX_FRAME_SIZE
|
8
|
+
|
9
|
+
4.3. Header Compression and Decompression
|
10
|
+
Sends invalid header block fragment
|
2
11
|
✓ Sends invalid header block fragment
|
12
|
+
Sends Dynamic Table Size Update (RFC 7541, 6.3)
|
3
13
|
✓ Sends Dynamic Table Size Update (RFC 7541, 6.3)
|
14
|
+
Encodes Dynamic Table Size Update (RFC 7541, 6.3) after common header fields
|
4
15
|
× Encodes Dynamic Table Size Update (RFC 7541, 6.3) after common header fields
|
16
|
+
- The endpoint MUST terminate the connection with a connection error of type COMPRESSION_ERROR.
|
17
|
+
Expected: GOAWAY frame (ErrorCode: COMPRESSION_ERROR)
|
18
|
+
Connection close
|
19
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
20
|
+
|
21
|
+
5.1. Stream States
|
22
|
+
idle: Sends a DATA frame
|
5
23
|
✓ idle: Sends a DATA frame
|
24
|
+
idle: Sends a RST_STREAM frame
|
6
25
|
✓ idle: Sends a RST_STREAM frame
|
26
|
+
idle: Sends a WINDOW_UPDATE frame
|
7
27
|
✓ idle: Sends a WINDOW_UPDATE frame
|
28
|
+
idle: Sends a CONTINUATION frame
|
8
29
|
✓ idle: Sends a CONTINUATION frame
|
30
|
+
half closed (remote): Sends a DATA frame
|
9
31
|
× half closed (remote): Sends a DATA frame
|
32
|
+
- The endpoint MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED.
|
33
|
+
Expected: GOAWAY frame (ErrorCode: STREAM_CLOSED)
|
34
|
+
RST_STREAM frame (ErrorCode: STREAM_CLOSED)
|
35
|
+
Connection close
|
36
|
+
Actual: WINDOW_UPDATE frame (Length: 4, Flags: 0)
|
37
|
+
half closed (remote): Sends a HEADERS frame
|
10
38
|
× half closed (remote): Sends a HEADERS frame
|
39
|
+
- The endpoint MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED.
|
40
|
+
Expected: GOAWAY frame (ErrorCode: STREAM_CLOSED)
|
41
|
+
RST_STREAM frame (ErrorCode: STREAM_CLOSED)
|
42
|
+
Connection close
|
43
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
44
|
+
half closed (remote): Sends a CONTINUATION frame
|
11
45
|
× half closed (remote): Sends a CONTINUATION frame
|
46
|
+
- The endpoint MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED.
|
47
|
+
Expected: GOAWAY frame (ErrorCode: STREAM_CLOSED)
|
48
|
+
RST_STREAM frame (ErrorCode: STREAM_CLOSED)
|
49
|
+
GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
50
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
51
|
+
Connection close
|
52
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
53
|
+
closed: Sends a CONTINUATION frame
|
12
54
|
× closed: Sends a CONTINUATION frame
|
55
|
+
- The endpoint MUST treat this as a stream error (Section 5.4.2) of type STREAM_CLOSED.
|
56
|
+
Expected: GOAWAY frame (ErrorCode: STREAM_CLOSED)
|
57
|
+
RST_STREAM frame (ErrorCode: STREAM_CLOSED)
|
58
|
+
GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
59
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
60
|
+
Connection close
|
61
|
+
Actual: Test timeout
|
62
|
+
|
63
|
+
5.1.1. Stream Identifiers
|
64
|
+
Sends even-numbered stream identifier
|
13
65
|
✓ Sends even-numbered stream identifier
|
66
|
+
|
67
|
+
5.1.2. Stream Concurrency
|
68
|
+
Sends HEADERS frames that causes their advertised concurrent stream limit to be exceeded
|
14
69
|
× Sends HEADERS frames that causes their advertised concurrent stream limit to be exceeded
|
70
|
+
- The endpoint MUST treat this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR or REFUSED_STREAM
|
71
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
72
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
73
|
+
GOAWAY frame (ErrorCode: REFUSED_STREAM)
|
74
|
+
RST_STREAM frame (ErrorCode: REFUSED_STREAM)
|
75
|
+
Connection close
|
76
|
+
Actual: HEADERS frame (Length: 3, Flags: 4)
|
77
|
+
|
78
|
+
5.3. Stream Priority
|
79
|
+
5.3.1. Stream Dependencies
|
80
|
+
Sends HEADERS frame that depend on itself
|
15
81
|
× Sends HEADERS frame that depend on itself
|
82
|
+
- The endpoint MUST treat this as a stream error of type PROTOCOL_ERROR
|
83
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
84
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
85
|
+
Connection close
|
86
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
87
|
+
Sends PRIORITY frame that depend on itself
|
16
88
|
× Sends PRIORITY frame that depend on itself
|
89
|
+
- The endpoint MUST treat this as a stream error of type PROTOCOL_ERROR
|
90
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
91
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
92
|
+
Connection close
|
93
|
+
Actual: Test timeout
|
94
|
+
|
95
|
+
5.5. Extending HTTP/2
|
96
|
+
Sends an unknown extension frame
|
17
97
|
✓ Sends an unknown extension frame
|
98
|
+
Sends an unknown extension frame in the middle of a header block
|
18
99
|
× Sends an unknown extension frame in the middle of a header block
|
100
|
+
- The endpoint MUST treat as a connection error of type PROTOCOL_ERROR.
|
101
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
102
|
+
Connection close
|
103
|
+
Actual: Test timeout
|
104
|
+
|
105
|
+
6.1. DATA
|
106
|
+
Sends a DATA frame with 0x0 stream identifier
|
19
107
|
✓ Sends a DATA frame with 0x0 stream identifier
|
108
|
+
Sends a DATA frame on the stream that is not in "open" or "half-closed (local)" state
|
20
109
|
× Sends a DATA frame on the stream that is not in "open" or "half-closed (local)" state
|
110
|
+
- The endpoint MUST respond with a stream error (Section 5.4.2) of type STREAM_CLOSED.
|
111
|
+
Expected: GOAWAY frame (ErrorCode: STREAM_CLOSED)
|
112
|
+
RST_STREAM frame (ErrorCode: STREAM_CLOSED)
|
113
|
+
Connection close
|
114
|
+
Actual: WINDOW_UPDATE frame (Length: 4, Flags: 0)
|
115
|
+
Sends a DATA frame with invalid pad length
|
21
116
|
✓ Sends a DATA frame with invalid pad length
|
117
|
+
|
118
|
+
6.2. HEADERS
|
119
|
+
Sends a HEADERS frame followed by any frame other than CONTINUATION
|
22
120
|
✓ Sends a HEADERS frame followed by any frame other than CONTINUATION
|
121
|
+
Sends a HEADERS frame followed by a frame on a different stream
|
23
122
|
× Sends a HEADERS frame followed by a frame on a different stream
|
123
|
+
- The endpoint MUST treat the receipt of a frame on a different stream as a connection error of type PROTOCOL_ERROR.
|
124
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
125
|
+
Connection close
|
126
|
+
Actual: Test timeout
|
127
|
+
Sends a HEADERS frame with 0x0 stream identifier
|
24
128
|
✓ Sends a HEADERS frame with 0x0 stream identifier
|
129
|
+
Sends a HEADERS frame with invalid pad length
|
25
130
|
✓ Sends a HEADERS frame with invalid pad length
|
131
|
+
|
132
|
+
6.3. PRIORITY
|
133
|
+
Sends a PRIORITY frame with 0x0 stream identifier
|
26
134
|
✓ Sends a PRIORITY frame with 0x0 stream identifier
|
135
|
+
Sends a PRIORITY frame with a length other than 5 octets
|
27
136
|
× Sends a PRIORITY frame with a length other than 5 octets
|
137
|
+
- The endpoint MUST respond with a stream error of type FRAME_SIZE_ERROR.
|
138
|
+
Expected: GOAWAY frame (ErrorCode: FRAME_SIZE_ERROR)
|
139
|
+
RST_STREAM frame (ErrorCode: FRAME_SIZE_ERROR)
|
140
|
+
Connection close
|
141
|
+
Actual: GOAWAY frame (Length: 8, Flags: 0, ErrorCode: PROTOCOL_ERROR)
|
142
|
+
|
143
|
+
6.4. RST_STREAM
|
144
|
+
Sends a RST_STREAM frame with 0x0 stream identifier
|
28
145
|
✓ Sends a RST_STREAM frame with 0x0 stream identifier
|
146
|
+
Sends a RST_STREAM frame on a idle stream
|
29
147
|
✓ Sends a RST_STREAM frame on a idle stream
|
148
|
+
Sends a RST_STREAM frame with a length other than 4 octets
|
30
149
|
× Sends a RST_STREAM frame with a length other than 4 octets
|
150
|
+
- The endpoint MUST respond with a connection error of type FRAME_SIZE_ERROR.
|
151
|
+
Expected: GOAWAY frame (ErrorCode: FRAME_SIZE_ERROR)
|
152
|
+
Connection close
|
153
|
+
Actual: GOAWAY frame (Length: 8, Flags: 0, ErrorCode: PROTOCOL_ERROR)
|
154
|
+
|
155
|
+
6.5. SETTINGS
|
156
|
+
Sends a SETTINGS frame
|
31
157
|
✓ Sends a SETTINGS frame
|
158
|
+
Sends a SETTINGS frame that is not a zero-length with ACK flag
|
32
159
|
✓ Sends a SETTINGS frame that is not a zero-length with ACK flag
|
160
|
+
Sends a SETTINGS frame with the stream identifier that is not 0x0
|
33
161
|
✓ Sends a SETTINGS frame with the stream identifier that is not 0x0
|
162
|
+
Sends a SETTINGS frame with a length other than a multiple of 6 octets
|
34
163
|
✓ Sends a SETTINGS frame with a length other than a multiple of 6 octets
|
164
|
+
|
165
|
+
6.5.2. Defined SETTINGS Parameters
|
166
|
+
SETTINGS_ENABLE_PUSH (0x2): Sends the value other than 0 or 1
|
35
167
|
✓ SETTINGS_ENABLE_PUSH (0x2): Sends the value other than 0 or 1
|
168
|
+
SETTINGS_INITIAL_WINDOW_SIZE (0x4): Sends the value above the maximum flow control window size
|
36
169
|
× SETTINGS_INITIAL_WINDOW_SIZE (0x4): Sends the value above the maximum flow control window size
|
170
|
+
- The endpoint MUST respond with a connection error of type FLOW_CONTROL_ERROR.
|
171
|
+
Expected: GOAWAY frame (ErrorCode: FLOW_CONTROL_ERROR)
|
172
|
+
Connection close
|
173
|
+
Actual: GOAWAY frame (Length: 8, Flags: 0, ErrorCode: PROTOCOL_ERROR)
|
174
|
+
SETTINGS_MAX_FRAME_SIZE (0x5): Sends the value below the initial value
|
37
175
|
✓ SETTINGS_MAX_FRAME_SIZE (0x5): Sends the value below the initial value
|
176
|
+
SETTINGS_MAX_FRAME_SIZE (0x5): Sends the value above the maximum allowed frame size
|
38
177
|
✓ SETTINGS_MAX_FRAME_SIZE (0x5): Sends the value above the maximum allowed frame size
|
178
|
+
|
179
|
+
6.7. PING
|
180
|
+
Sends a PING frame
|
39
181
|
✓ Sends a PING frame
|
182
|
+
Sends a PING frame with the stream identifier that is not 0x0
|
40
183
|
× Sends a PING frame with the stream identifier that is not 0x0
|
184
|
+
- The endpoint MUST respond with a connection error of type PROTOCOL_ERROR.
|
185
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
186
|
+
Connection close
|
187
|
+
Actual: PING frame (Length: 8, Flags: 1)
|
188
|
+
Sends a PING frame with a length field value other than 8
|
41
189
|
✓ Sends a PING frame with a length field value other than 8
|
190
|
+
|
191
|
+
6.8. GOAWAY
|
192
|
+
Sends a GOAWAY frame with the stream identifier that is not 0x0
|
42
193
|
× Sends a GOAWAY frame with the stream identifier that is not 0x0
|
194
|
+
- The endpoint MUST respond with a connection error of type PROTOCOL_ERROR.
|
195
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
196
|
+
Connection close
|
197
|
+
Actual: Test timeout
|
198
|
+
|
199
|
+
6.9. WINDOW_UPDATE
|
200
|
+
Sends a WINDOW_UPDATE frame
|
43
201
|
× Sends a WINDOW_UPDATE frame
|
202
|
+
- The endpoint is expected to send the DATA frame based on the window size.
|
203
|
+
Expected: DATA frame
|
204
|
+
Actual: Test timeout
|
205
|
+
Sends a WINDOW_UPDATE frame with a flow control window increment of 0
|
44
206
|
× Sends a WINDOW_UPDATE frame with a flow control window increment of 0
|
207
|
+
- The endpoint MUST respond with a connection error of type PROTOCOL_ERROR.
|
208
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
209
|
+
Connection close
|
210
|
+
Actual: Test timeout
|
211
|
+
Sends a WINDOW_UPDATE frame with a flow control window increment of 0 on a stream
|
45
212
|
× Sends a WINDOW_UPDATE frame with a flow control window increment of 0 on a stream
|
213
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
214
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
215
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
216
|
+
Connection close
|
217
|
+
Actual: SETTINGS frame (Length: 0, Flags: 1)
|
218
|
+
Sends a WINDOW_UPDATE frame with a length other than a multiple of 4 octets
|
46
219
|
× Sends a WINDOW_UPDATE frame with a length other than a multiple of 4 octets
|
220
|
+
- The endpoint MUST respond with a connection error of type FRAME_SIZE_ERROR.
|
221
|
+
Expected: GOAWAY frame (ErrorCode: FRAME_SIZE_ERROR)
|
222
|
+
Connection close
|
223
|
+
Actual: GOAWAY frame (Length: 8, Flags: 0, ErrorCode: PROTOCOL_ERROR)
|
224
|
+
|
225
|
+
6.9.1. The Flow Control Window
|
226
|
+
Sends multiple WINDOW_UPDATE frames on a connection increasing the flow control window to above 2^31-1
|
47
227
|
× Sends multiple WINDOW_UPDATE frames on a connection increasing the flow control window to above 2^31-1
|
228
|
+
- The endpoint MUST sends a GOAWAY frame with a FLOW_CONTROL_ERROR code.
|
229
|
+
Expected: GOAWAY frame (ErrorCode: FLOW_CONTROL_ERROR)
|
230
|
+
Actual: Test timeout
|
231
|
+
Sends multiple WINDOW_UPDATE frames on a stream increasing the flow control window to above 2^31-1
|
48
232
|
× Sends multiple WINDOW_UPDATE frames on a stream increasing the flow control window to above 2^31-1
|
233
|
+
- The endpoint MUST send a RST_STREAM with the error code of FLOW_CONTROL_ERROR code.
|
234
|
+
Expected: RST_STREAM frame (ErrorCode: FLOW_CONTROL_ERROR)
|
235
|
+
GOAWAY frame (ErrorCode: FLOW_CONTROL_ERROR)
|
236
|
+
Actual: Test timeout
|
237
|
+
|
238
|
+
6.9.2. Initial Flow Control Window Size
|
239
|
+
Sends a SETTINGS_INITIAL_WINDOW_SIZE settings with an exceeded maximum window size value
|
49
240
|
× Sends a SETTINGS_INITIAL_WINDOW_SIZE settings with an exceeded maximum window size value
|
241
|
+
- The endpoint MUST respond with a connection error of type FLOW_CONTROL_ERROR.
|
242
|
+
Expected: GOAWAY frame (ErrorCode: FLOW_CONTROL_ERROR)
|
243
|
+
Connection close
|
244
|
+
Actual: GOAWAY frame (Length: 8, Flags: 0, ErrorCode: PROTOCOL_ERROR)
|
245
|
+
|
246
|
+
6.10. CONTINUATION
|
247
|
+
Sends a CONTINUATION frame
|
50
248
|
✓ Sends a CONTINUATION frame
|
249
|
+
Sends multiple CONTINUATION frames
|
51
250
|
✓ Sends multiple CONTINUATION frames
|
251
|
+
Sends a CONTINUATION frame followed by any frame other than CONTINUATION
|
52
252
|
× Sends a CONTINUATION frame followed by any frame other than CONTINUATION
|
253
|
+
- The endpoint MUST treat as a connection error of type PROTOCOL_ERROR.
|
254
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
255
|
+
Connection close
|
256
|
+
Actual: Test timeout
|
257
|
+
Sends a CONTINUATION frame followed by a frame on a different stream
|
53
258
|
✓ Sends a CONTINUATION frame followed by a frame on a different stream
|
259
|
+
Sends a CONTINUATION frame with the stream identifier that is 0x0
|
54
260
|
✓ Sends a CONTINUATION frame with the stream identifier that is 0x0
|
261
|
+
Sends a CONTINUATION frame after the frame other than HEADERS, PUSH_PROMISE or CONTINUATION
|
55
262
|
× Sends a CONTINUATION frame after the frame other than HEADERS, PUSH_PROMISE or CONTINUATION
|
263
|
+
- The endpoint MUST treat as a connection error of type PROTOCOL_ERROR.
|
264
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
265
|
+
Connection close
|
266
|
+
Actual: WINDOW_UPDATE frame (Length: 4, Flags: 0)
|
267
|
+
|
268
|
+
8.1. HTTP Request/Response Exchange
|
269
|
+
Sends a HEADERS frame as HEAD request
|
56
270
|
× Sends a HEADERS frame as HEAD request
|
271
|
+
- The endpoint should respond with no DATA frame or empty DATA frame.
|
272
|
+
Expected: HEADERS frame (Flags: 1)
|
273
|
+
DATA frame (Length: 0, Flags: 1)
|
274
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
275
|
+
Sends a HEADERS frame containing trailer part
|
57
276
|
✓ Sends a HEADERS frame containing trailer part
|
277
|
+
Sends a second HEADERS frame without the END_STREAM flag
|
58
278
|
× Sends a second HEADERS frame without the END_STREAM flag
|
279
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
280
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
281
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
282
|
+
Connection close
|
283
|
+
Actual: WINDOW_UPDATE frame (Length: 4, Flags: 0)
|
284
|
+
|
285
|
+
8.1.2. HTTP Header Fields
|
286
|
+
Sends a HEADERS frame that contains the header field name in uppercase letters
|
59
287
|
× Sends a HEADERS frame that contains the header field name in uppercase letters
|
288
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
289
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
290
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
291
|
+
Connection close
|
292
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
293
|
+
|
294
|
+
8.1.2.1. Pseudo-Header Fields
|
295
|
+
Sends a HEADERS frame that contains the pseudo-header field defined for response
|
60
296
|
× Sends a HEADERS frame that contains the pseudo-header field defined for response
|
297
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
298
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
299
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
300
|
+
Connection close
|
301
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
302
|
+
Sends a HEADERS frame that contains the invalid pseudo-header field
|
61
303
|
× Sends a HEADERS frame that contains the invalid pseudo-header field
|
304
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
305
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
306
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
307
|
+
Connection close
|
308
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
309
|
+
Sends a HEADERS frame that contains a pseudo-header field that appears in a header block after a regular header field
|
62
310
|
× Sends a HEADERS frame that contains a pseudo-header field that appears in a header block after a regular header field
|
311
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
312
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
313
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
314
|
+
Connection close
|
315
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
316
|
+
|
317
|
+
8.1.2.2. Connection-Specific Header Fields
|
318
|
+
Sends a HEADERS frame that contains the connection-specific header field
|
63
319
|
× Sends a HEADERS frame that contains the connection-specific header field
|
320
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
321
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
322
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
323
|
+
Connection close
|
324
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
325
|
+
Sends a HEADERS frame that contains the TE header field that contain any value other than "trailers"
|
64
326
|
× Sends a HEADERS frame that contains the TE header field that contain any value other than "trailers"
|
327
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
328
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
329
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
330
|
+
Connection close
|
331
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
332
|
+
|
333
|
+
8.1.2.3. Request Pseudo-Header Fields
|
334
|
+
Sends a HEADERS frame that omits mandatory pseudo-header fields
|
65
335
|
× Sends a HEADERS frame that omits mandatory pseudo-header fields
|
336
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
337
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
338
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
339
|
+
Connection close
|
340
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
341
|
+
Sends a HEADERS frame that omits just ':method' pseudo-header field.
|
66
342
|
× Sends a HEADERS frame that omits just ':method' pseudo-header field.
|
343
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
344
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
345
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
346
|
+
Connection close
|
347
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
348
|
+
Sends a HEADERS frame that omits just ':scheme' pseudo-header field.
|
67
349
|
× Sends a HEADERS frame that omits just ':scheme' pseudo-header field.
|
350
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
351
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
352
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
353
|
+
Connection close
|
354
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
355
|
+
Sends a HEADERS frame that omits just ':path' pseudo-header field.
|
68
356
|
× Sends a HEADERS frame that omits just ':path' pseudo-header field.
|
357
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
358
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
359
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
360
|
+
Connection close
|
361
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
362
|
+
Sends a HEADERS frame containing more than one pseudo-header fields with the same name
|
69
363
|
× Sends a HEADERS frame containing more than one pseudo-header fields with the same name
|
364
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
365
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
366
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
367
|
+
Connection close
|
368
|
+
Actual: DATA frame (Length: 22, Flags: 1)
|
369
|
+
|
370
|
+
8.1.2.6. Malformed Requests and Responses
|
371
|
+
Sends a HEADERS frame that contains the "content-length" header field which does not equal the sum of the DATA frame payload lengths
|
70
372
|
× Sends a HEADERS frame that contains the "content-length" header field which does not equal the sum of the DATA frame payload lengths
|
373
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
374
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
375
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
376
|
+
Connection close
|
377
|
+
Actual: DATA frame (Length: 29, Flags: 1)
|
378
|
+
Sends a HEADERS frame that contains the "content-length" header field which does not equal the sum of the multiple DATA frame payload lengths
|
71
379
|
× Sends a HEADERS frame that contains the "content-length" header field which does not equal the sum of the multiple DATA frame payload lengths
|
380
|
+
- The endpoint MUST respond with a stream error of type PROTOCOL_ERROR.
|
381
|
+
Expected: GOAWAY frame (ErrorCode: PROTOCOL_ERROR)
|
382
|
+
RST_STREAM frame (ErrorCode: PROTOCOL_ERROR)
|
383
|
+
Connection close
|
384
|
+
Actual: DATA frame (Length: 33, Flags: 1)
|
385
|
+
|
386
|
+
8.2. Server Push
|
387
|
+
Sends a PUSH_PROMISE frame
|
72
388
|
✓ Sends a PUSH_PROMISE frame
|
389
|
+
|
390
|
+
73 tests, 33 passed, 0 skipped, 40 failed
|