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
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-----
|