http-2 0.8.2 → 0.8.3
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/.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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b7732a1022ca5c6c097c2b575ef214e7118d2646
|
4
|
+
data.tar.gz: 6d9def6bbeb440c2070edb5bd3cc38313cd360fe
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c166616d45fdf27d87514770287e409dcdc97a5f0e821fe4da970fd99b3487cbbe7b2679d99e055d3b04474eb92bf27cd8655509d5facc55315a351b1a1d2246
|
7
|
+
data.tar.gz: a6888d5a873081b38bd2245f7c6c1be6cf456b5a39b7adc595b8b693fcac31fc50f3bd876c6293f93c76ec37cdb924aa846562eff71215d5e4af60bf282e452f
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
@@ -1,9 +1,15 @@
|
|
1
1
|
inherit_from: .rubocop_todo.yml
|
2
2
|
|
3
3
|
AllCops:
|
4
|
+
TargetRubyVersion: 2.1
|
4
5
|
DisplayCopNames: true
|
5
6
|
Exclude:
|
6
|
-
- 'bin
|
7
|
+
- 'bin/**'
|
8
|
+
- 'vendor/**/*'
|
9
|
+
- '**/huffman_statemachine.rb'
|
10
|
+
|
11
|
+
Metrics/LineLength:
|
12
|
+
Max: 120
|
7
13
|
|
8
14
|
Lint/EndAlignment:
|
9
15
|
AlignWith: variable
|
@@ -14,5 +20,38 @@ Style/CaseIndentation:
|
|
14
20
|
Style/IndentHash:
|
15
21
|
EnforcedStyle: consistent
|
16
22
|
|
17
|
-
Style/
|
23
|
+
Style/TrailingCommaInLiteral:
|
18
24
|
EnforcedStyleForMultiline: comma
|
25
|
+
|
26
|
+
Style/SpaceAroundOperators:
|
27
|
+
Enabled: false
|
28
|
+
|
29
|
+
Style/ExtraSpacing:
|
30
|
+
Enabled: false
|
31
|
+
|
32
|
+
Style/SignalException:
|
33
|
+
Enabled: false
|
34
|
+
|
35
|
+
Style/FrozenStringLiteralComment:
|
36
|
+
Enabled: false
|
37
|
+
|
38
|
+
Style/ParallelAssignment:
|
39
|
+
Enabled: false
|
40
|
+
|
41
|
+
Style/ParenthesesAroundCondition:
|
42
|
+
Enabled: false
|
43
|
+
|
44
|
+
Style/IfInsideElse:
|
45
|
+
Enabled: false
|
46
|
+
|
47
|
+
Style/TrailingCommaInArguments:
|
48
|
+
Enabled: false
|
49
|
+
|
50
|
+
Style/TrailingUnderscoreVariable:
|
51
|
+
Enabled: false
|
52
|
+
|
53
|
+
Performance/TimesMap:
|
54
|
+
Enabled: false
|
55
|
+
|
56
|
+
Performance/RedundantBlockCall:
|
57
|
+
Enabled: false
|
data/.rubocop_todo.yml
CHANGED
@@ -1,33 +1,35 @@
|
|
1
|
-
# This configuration was generated by
|
2
|
-
#
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2016-06-09 10:57:54 -0400 using RuboCop version 0.40.0.
|
3
4
|
# The point is for the user to remove these configuration records
|
4
5
|
# one by one as the offenses are removed from the code base.
|
5
6
|
# Note that changes in the inspected code, or installation of new
|
6
7
|
# versions of RuboCop, may require this file to be generated again.
|
7
8
|
|
8
|
-
# Offense count:
|
9
|
+
# Offense count: 24
|
9
10
|
Metrics/AbcSize:
|
10
|
-
Max:
|
11
|
+
Max: 185
|
11
12
|
|
12
13
|
# Offense count: 16
|
13
14
|
Metrics/BlockNesting:
|
14
15
|
Max: 5
|
15
16
|
|
16
|
-
# Offense count:
|
17
|
+
# Offense count: 5
|
17
18
|
# Configuration parameters: CountComments.
|
18
19
|
Metrics/ClassLength:
|
19
|
-
Max:
|
20
|
+
Max: 325
|
20
21
|
|
21
22
|
# Offense count: 12
|
22
23
|
Metrics/CyclomaticComplexity:
|
23
24
|
Max: 60
|
24
25
|
|
25
|
-
# Offense count:
|
26
|
-
# Configuration parameters: AllowURI, URISchemes.
|
26
|
+
# Offense count: 9
|
27
|
+
# Configuration parameters: AllowHeredoc, AllowURI, URISchemes.
|
28
|
+
# URISchemes: http, https
|
27
29
|
Metrics/LineLength:
|
28
|
-
Max:
|
30
|
+
Max: 108
|
29
31
|
|
30
|
-
# Offense count:
|
32
|
+
# Offense count: 29
|
31
33
|
# Configuration parameters: CountComments.
|
32
34
|
Metrics/MethodLength:
|
33
35
|
Max: 134
|
@@ -41,6 +43,77 @@ Metrics/ParameterLists:
|
|
41
43
|
Metrics/PerceivedComplexity:
|
42
44
|
Max: 46
|
43
45
|
|
44
|
-
# Offense count:
|
46
|
+
# Offense count: 1
|
47
|
+
# Cop supports --auto-correct.
|
48
|
+
# Configuration parameters: MaxKeyValuePairs.
|
49
|
+
Performance/RedundantMerge:
|
50
|
+
Exclude:
|
51
|
+
- 'lib/http/2/server.rb'
|
52
|
+
|
53
|
+
# Offense count: 4
|
45
54
|
Style/Documentation:
|
46
|
-
|
55
|
+
Exclude:
|
56
|
+
- 'spec/**/*'
|
57
|
+
- 'test/**/*'
|
58
|
+
- 'example/helper.rb'
|
59
|
+
- 'example/upgrade_server.rb'
|
60
|
+
- 'lib/tasks/generate_huffman_table.rb'
|
61
|
+
|
62
|
+
# Offense count: 1
|
63
|
+
# Cop supports --auto-correct.
|
64
|
+
Style/EmptyCaseCondition:
|
65
|
+
Exclude:
|
66
|
+
- 'example/upgrade_server.rb'
|
67
|
+
|
68
|
+
# Offense count: 1
|
69
|
+
# Configuration parameters: MinBodyLength.
|
70
|
+
Style/GuardClause:
|
71
|
+
Exclude:
|
72
|
+
- 'lib/http/2/connection.rb'
|
73
|
+
|
74
|
+
# Offense count: 2
|
75
|
+
# Cop supports --auto-correct.
|
76
|
+
# Configuration parameters: SupportedStyles, IndentationWidth.
|
77
|
+
# SupportedStyles: special_inside_parentheses, consistent, align_brackets
|
78
|
+
Style/IndentArray:
|
79
|
+
EnforcedStyle: consistent
|
80
|
+
|
81
|
+
# Offense count: 1
|
82
|
+
# Cop supports --auto-correct.
|
83
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
84
|
+
# SupportedStyles: symmetrical, new_line, same_line
|
85
|
+
Style/MultilineArrayBraceLayout:
|
86
|
+
Exclude:
|
87
|
+
- 'spec/compressor_spec.rb'
|
88
|
+
|
89
|
+
# Offense count: 16
|
90
|
+
# Cop supports --auto-correct.
|
91
|
+
# Configuration parameters: EnforcedStyle, SupportedStyles.
|
92
|
+
# SupportedStyles: symmetrical, new_line, same_line
|
93
|
+
Style/MultilineHashBraceLayout:
|
94
|
+
Exclude:
|
95
|
+
- 'spec/compressor_spec.rb'
|
96
|
+
|
97
|
+
# Offense count: 1
|
98
|
+
# Cop supports --auto-correct.
|
99
|
+
Style/MutableConstant:
|
100
|
+
Exclude:
|
101
|
+
- 'example/upgrade_server.rb'
|
102
|
+
|
103
|
+
# Offense count: 1
|
104
|
+
# Cop supports --auto-correct.
|
105
|
+
Style/RedundantSelf:
|
106
|
+
Exclude:
|
107
|
+
- 'lib/http/2/connection.rb'
|
108
|
+
|
109
|
+
# Offense count: 1
|
110
|
+
# Cop supports --auto-correct.
|
111
|
+
Style/UnneededInterpolation:
|
112
|
+
Exclude:
|
113
|
+
- 'spec/compressor_spec.rb'
|
114
|
+
|
115
|
+
# Offense count: 1
|
116
|
+
# Cop supports --auto-correct.
|
117
|
+
Style/ZeroLengthPredicate:
|
118
|
+
Exclude:
|
119
|
+
- 'lib/http/2/framer.rb'
|
data/Gemfile
CHANGED
@@ -4,14 +4,13 @@ gem 'rake'
|
|
4
4
|
gem 'yard'
|
5
5
|
|
6
6
|
group :test do
|
7
|
-
gem 'activesupport'
|
8
7
|
gem 'autotest-standalone'
|
9
8
|
gem 'coveralls', require: false
|
10
9
|
gem 'pry'
|
11
10
|
gem 'pry-byebug', platform: :mri
|
12
11
|
gem 'rspec', '~> 3.4.0'
|
13
12
|
gem 'rspec-autotest'
|
14
|
-
gem 'rubocop', '
|
13
|
+
gem 'rubocop', '0.43.0'
|
15
14
|
end
|
16
15
|
|
17
16
|
gemspec
|
data/Guardfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
guard :process, name: 'HTTP/2 Server', command: 'ruby example/server.rb', stop_signal: 'TERM' do
|
3
|
+
watch(%r{^example/(.+)\.rb$})
|
4
|
+
watch(%r{^lib/http/2/(.+)\.rb$})
|
5
|
+
|
6
|
+
watch('Gemfile.lock')
|
7
|
+
end
|
8
|
+
|
9
|
+
def h2spec
|
10
|
+
puts 'Starting H2 Spec'
|
11
|
+
sleep 0.7
|
12
|
+
system '~/go-workspace/bin/h2spec -p 8080 -o 1 -s 4.2'
|
13
|
+
puts "\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
guard :shell, name: 'H2 Spec' do
|
17
|
+
watch(%r{^example/(.+)\.rb$}) { h2spec }
|
18
|
+
watch(%r{^lib/http/2/(.+)\.rb$}) { h2spec }
|
19
|
+
end
|
data/Guardfile.h2spec
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
def h2spec
|
2
|
+
puts "Starting H2 Spec"
|
3
|
+
sleep 0.7
|
4
|
+
system '~/go-workspace/bin/h2spec -p 8080 -o 1 -s 5.1'
|
5
|
+
puts "\n"
|
6
|
+
end
|
7
|
+
|
8
|
+
guard :shell, name:'H2 Spec' do
|
9
|
+
watch(%r{^example/(.+)\.rb$}) { h2spec }
|
10
|
+
watch(%r{^lib/http/2/(.+)\.rb$}) { h2spec }
|
11
|
+
end
|
12
|
+
|
data/README.md
CHANGED
@@ -239,16 +239,16 @@ conn.on(:stream) do |stream|
|
|
239
239
|
|
240
240
|
# fires when client terminates its request (i.e. request finished)
|
241
241
|
stream.on(:half_close) do
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
}
|
242
|
+
promise_header = { ':method' => 'GET',
|
243
|
+
':authority' => 'localhost',
|
244
|
+
':scheme' => 'https',
|
245
|
+
':path' => "/other_resource" }
|
247
246
|
|
248
247
|
# initiate server push stream
|
249
|
-
|
250
|
-
|
251
|
-
push.
|
248
|
+
push_stream = nil
|
249
|
+
stream.promise(promise_header) do |push|
|
250
|
+
push.headers({...})
|
251
|
+
push_stream = push
|
252
252
|
end
|
253
253
|
|
254
254
|
# send response
|
@@ -259,8 +259,10 @@ conn.on(:stream) do |stream|
|
|
259
259
|
|
260
260
|
# split response between multiple DATA frames
|
261
261
|
stream.data(response_chunk, end_stream: false)
|
262
|
-
promise.data(payload)
|
263
262
|
stream.data(last_chunk)
|
263
|
+
|
264
|
+
# now send the previously promised data
|
265
|
+
push_stream.data(push_data)
|
264
266
|
end
|
265
267
|
end
|
266
268
|
```
|
@@ -279,6 +281,13 @@ The client can cancel any given push stream (via `.close`), or disable server pu
|
|
279
281
|
```ruby
|
280
282
|
client.settings(streams: 0) # setting max limit to 0 disables server push
|
281
283
|
```
|
284
|
+
### Specs
|
285
|
+
|
286
|
+
To run specs:
|
287
|
+
|
288
|
+
```ruby
|
289
|
+
rake
|
290
|
+
```
|
282
291
|
|
283
292
|
### License
|
284
293
|
|
data/Rakefile
CHANGED
@@ -2,10 +2,48 @@ require 'bundler/gem_tasks'
|
|
2
2
|
require 'rspec/core/rake_task'
|
3
3
|
require 'rubocop/rake_task'
|
4
4
|
require 'yard'
|
5
|
+
require 'open3'
|
5
6
|
require_relative 'lib/tasks/generate_huffman_table'
|
6
7
|
|
7
|
-
RSpec::Core::RakeTask.new
|
8
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
9
|
+
t.exclude_pattern = './spec/hpack_test_spec.rb'
|
10
|
+
end
|
11
|
+
|
12
|
+
RSpec::Core::RakeTask.new(:hpack) do |t|
|
13
|
+
t.pattern = './spec/hpack_test_spec.rb'
|
14
|
+
end
|
15
|
+
|
16
|
+
task :h2spec do
|
17
|
+
if /darwin/ !~ RUBY_PLATFORM
|
18
|
+
abort "h2spec rake task currently only works on OSX.
|
19
|
+
Download other binaries from https://github.com/summerwind/h2spec/releases"
|
20
|
+
end
|
21
|
+
|
22
|
+
system 'ruby example/server.rb -p 9000 &', out: File::NULL
|
23
|
+
sleep 1
|
24
|
+
|
25
|
+
output = ''
|
26
|
+
Open3.popen2e('spec/h2spec/h2spec.darwin -p 9000 -o 1') do |_i, oe, _t|
|
27
|
+
oe.each do |l|
|
28
|
+
l.gsub!(/\e\[(\d+)(;\d+)*m/, '')
|
29
|
+
|
30
|
+
output << l
|
31
|
+
if l =~ /passed.*failed/
|
32
|
+
puts "\n#{l}"
|
33
|
+
break # suppress post-summary failure output
|
34
|
+
else
|
35
|
+
print '.'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
File.write 'spec/h2spec/output/non_secure.txt', output
|
41
|
+
|
42
|
+
system 'kill `pgrep -f example/server.rb`'
|
43
|
+
end
|
44
|
+
|
8
45
|
RuboCop::RakeTask.new
|
9
46
|
YARD::Rake::YardocTask.new
|
10
47
|
|
11
48
|
task default: [:spec, :rubocop]
|
49
|
+
task all: [:default, :hpack]
|
data/example/Gemfile
ADDED
data/example/README.md
CHANGED
@@ -8,6 +8,10 @@ $> ruby server.rb
|
|
8
8
|
$> ruby client.rb http://localhost:8080/ # GET
|
9
9
|
$> ruby client.rb http://localhost:8080/ -d 'some data' # POST
|
10
10
|
|
11
|
+
# Server push
|
12
|
+
$> ruby server.rb --push
|
13
|
+
$> ruby client.rb http://localhost:8080/ # GET
|
14
|
+
|
11
15
|
# TLS + NPN negotiation
|
12
16
|
$> ruby server.rb --secure
|
13
17
|
$> ruby client.rb https://localhost:8080/ # GET
|
data/example/client.rb
CHANGED
@@ -17,9 +17,11 @@ if uri.scheme == 'https'
|
|
17
17
|
ctx = OpenSSL::SSL::SSLContext.new
|
18
18
|
ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
# For ALPN support, Ruby >= 2.3 and OpenSSL >= 1.0.2 are required
|
21
|
+
|
22
|
+
ctx.alpn_protocols = [DRAFT]
|
23
|
+
ctx.alpn_select_cb = lambda do |protocols|
|
24
|
+
puts "ALPN protocols supported by server: #{protocols}"
|
23
25
|
DRAFT if protocols.include? DRAFT
|
24
26
|
end
|
25
27
|
|
@@ -28,8 +30,8 @@ if uri.scheme == 'https'
|
|
28
30
|
sock.hostname = uri.hostname
|
29
31
|
sock.connect
|
30
32
|
|
31
|
-
if sock.
|
32
|
-
puts "Failed to negotiate #{DRAFT} via
|
33
|
+
if sock.alpn_protocol != DRAFT
|
34
|
+
puts "Failed to negotiate #{DRAFT} via ALPN"
|
33
35
|
exit
|
34
36
|
end
|
35
37
|
else
|
@@ -37,6 +39,9 @@ else
|
|
37
39
|
end
|
38
40
|
|
39
41
|
conn = HTTP2::Client.new
|
42
|
+
stream = conn.new_stream
|
43
|
+
log = Logger.new(stream.id)
|
44
|
+
|
40
45
|
conn.on(:frame) do |bytes|
|
41
46
|
# puts "Sending bytes: #{bytes.unpack("H*").first}"
|
42
47
|
sock.print bytes
|
@@ -49,9 +54,6 @@ conn.on(:frame_received) do |frame|
|
|
49
54
|
puts "Received frame: #{frame.inspect}"
|
50
55
|
end
|
51
56
|
|
52
|
-
stream = conn.new_stream
|
53
|
-
log = Logger.new(stream.id)
|
54
|
-
|
55
57
|
conn.on(:promise) do |promise|
|
56
58
|
promise.on(:headers) do |h|
|
57
59
|
log.info "promise headers: #{h}"
|
@@ -68,7 +70,6 @@ end
|
|
68
70
|
|
69
71
|
stream.on(:close) do
|
70
72
|
log.info 'stream closed'
|
71
|
-
sock.close
|
72
73
|
end
|
73
74
|
|
74
75
|
stream.on(:half_close) do
|
data/example/helper.rb
CHANGED
@@ -0,0 +1,20 @@
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
2
|
+
MIIDLjCCAhYCCQDIZ/9hq/2pXjANBgkqhkiG9w0BAQUFADBZMQswCQYDVQQGEwJB
|
3
|
+
VTETMBEGA1UECBMKU29tZS1TdGF0ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0
|
4
|
+
cyBQdHkgTHRkMRIwEAYDVQQDEwlsb2NhbGhvc3QwHhcNMTYwNjA2MTk0MzI1WhcN
|
5
|
+
MTcwNjA2MTk0MzI1WjBZMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0
|
6
|
+
ZTEhMB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMRIwEAYDVQQDEwls
|
7
|
+
b2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCjFXrWqtRZ
|
8
|
+
EMOO/o6AxGbgDYMgg/7uxCFQJM5Z6C4II6D8V94FDyCd+J0LOK2hB+QUdFqpA1S9
|
9
|
+
6RW2MvIwdvRt03RJMgbfcUF0+w4ZItv2xrW9waCfCmLSRDZgcSATacEF6u9p2Vs+
|
10
|
+
o4J/cHacirSwjy4+m94CgkxtUFGtGcJaFqAZ6Cdj5WvQdJSiAI3x3gNC/UGA+5dL
|
11
|
+
sp8+vwWx+/TMc6nDBmoRW3GHeG/NApQSh01w3wDv0FmUaFQlA5WPya/Js+CyuYh1
|
12
|
+
miXbQJEjDnGGaJjnoyRAQpPrk72Jj+bnfOu9kxpzkuLJOsbaofRFkM+/Ar5U+bQz
|
13
|
+
uU0ErQ8Ih8MPAgMBAAEwDQYJKoZIhvcNAQEFBQADggEBACL8HkKjW8kWLlW4TE5K
|
14
|
+
EcfsBad2Ah5ugTocJ/pLnr/YEo8uD91gECDtsuFTXul9n2M7U5jJmzbHZ63cjyC3
|
15
|
+
lb1BxJxUL7aIyaL61IMMcIJMWhC9VGnFUshMDNVBhuRkKs/QvaMD5KefKN1E9I2M
|
16
|
+
mZ72Yww0VihYwNOu3MTn8gUuy9eU6k/gTYPY7PJVh18QmR+Fs2MaaPp+bDwxiqML
|
17
|
+
0o2I6+0ZsqM3vFtcUjxjRASV5s+JkM34pTWFwUOl7TZv1YsxCKSz4f0BXDImZEvU
|
18
|
+
rwqFdlELp5WOG9LJsrszDRbf1wbFUsG1XXZpIBiWo3d6pOiIyRKrak1vKViNfYvI
|
19
|
+
W30=
|
20
|
+
-----END CERTIFICATE-----
|