h2 0.3.1 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +6 -5
- data/CHANGELOG.md +8 -0
- data/Gemfile +3 -2
- data/Guardfile +3 -0
- data/bin/console +1 -18
- data/exe/h2 +4 -0
- data/h2.gemspec +3 -5
- data/lib/h2/client/tcp_socket.rb +35 -14
- data/lib/h2/client.rb +39 -6
- data/lib/h2/version.rb +21 -1
- data/lib/h2.rb +8 -4
- metadata +7 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59101b19f83a2994cc9186c11121c95645e5cdf4
|
4
|
+
data.tar.gz: fd22e1173757e89c855641daf391e9b55de79204
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3431f613af4aea436ae44e2ef3e617408012553bf9d3b5ab36b6d4d0068d46d7485560b02037cb98b6eac7edaa8d07f3b79350e150c57330c4fe8f66c2d8a4be
|
7
|
+
data.tar.gz: f8e98e3d6838005d1c83848a35f48166eeb76a06dc87b53b9cf03c7ea6543c7b339285626a9d8de9a4ce90e2d1859babd3b78cd4e2d51f0088541e91f84dcee1
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
h2 changelog
|
2
2
|
============
|
3
3
|
|
4
|
+
### 0.4.0 17 jun 2017
|
5
|
+
|
6
|
+
* downgrade required ruby version to 2.2
|
7
|
+
* update .travis.yml for latest supported versions
|
8
|
+
* refactor exceptionless IO handling to prepended modules
|
9
|
+
* refactor On#on for lack of safe-nil operator
|
10
|
+
* refactor SSL context handling for 2.2/jruby
|
11
|
+
|
4
12
|
### 0.3.1 13 may 2017
|
5
13
|
|
6
14
|
* `servername` should not be set on client socket when IP address (#1)
|
data/Gemfile
CHANGED
@@ -12,6 +12,7 @@ end
|
|
12
12
|
|
13
13
|
group :development, :test do
|
14
14
|
gem 'awesome_print'
|
15
|
-
gem '
|
16
|
-
gem '
|
15
|
+
gem 'guard-rake'
|
16
|
+
gem 'pry-byebug', platforms: [:mri]
|
17
|
+
gem 'reel', require: 'reel/h2', git: 'https://github.com/kenichi/reel', branch: 'rebase_h2'
|
17
18
|
end
|
data/Guardfile
ADDED
data/bin/console
CHANGED
@@ -4,22 +4,5 @@ require 'bundler/setup'
|
|
4
4
|
require 'h2'
|
5
5
|
require 'irb'
|
6
6
|
|
7
|
-
|
8
|
-
|
9
|
-
def trunc_payload f
|
10
|
-
x = f.dup
|
11
|
-
size = x[:payload]&.to_s&.bytesize || 0
|
12
|
-
x[:payload] = "#{size} redacted" if size > 64
|
13
|
-
x
|
14
|
-
end
|
15
|
-
|
16
|
-
def new_client
|
17
|
-
# H2::Client.new url: 'https://127.0.0.1:4430', tls: { ca_file: '/Users/ken/src/ruby/other_reel/tmp/certs/ca.crt' } do |client|
|
18
|
-
# H2::Client.new url: 'http://127.0.0.1:1234' do |client|
|
19
|
-
H2::Client.new url: 'https://vux.nakamura.io:4430', tls: { ca_file: '/usr/local/etc/cacert-201611290415.pem' } do |client|
|
20
|
-
client.client.on(:frame_sent){|f| STDERR.puts ">> #{trunc_payload(f).inspect}"}
|
21
|
-
client.client.on(:frame_received){|f| STDERR.puts "<< #{trunc_payload(f).inspect}"}
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
7
|
+
Bundler.require :development
|
25
8
|
IRB.start
|
data/exe/h2
CHANGED
data/h2.gemspec
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
require_relative './lib/h2/version'
|
3
3
|
|
4
|
-
IGNORE = %w[ test/ spec/ features/ .gitignore .travis.yml ]
|
5
|
-
|
6
4
|
Gem::Specification.new do |spec|
|
7
5
|
spec.name = "h2"
|
8
6
|
spec.version = H2::VERSION
|
9
7
|
spec.authors = ["Kenichi Nakamura"]
|
10
8
|
spec.email = ["kenichi.nakamura@gmail.com"]
|
11
9
|
spec.summary = 'an http/2 client based on http-2 and modern ruby'
|
12
|
-
spec.description = 'a pure ruby http/2 client based on http-2 for ruby 2.
|
10
|
+
spec.description = 'a pure ruby http/2 client based on http-2 for ruby 2.2 and above'
|
13
11
|
spec.homepage = 'https://github.com/kenichi/h2'
|
14
12
|
spec.license = 'MIT'
|
15
13
|
spec.bindir = 'exe'
|
@@ -17,12 +15,12 @@ Gem::Specification.new do |spec|
|
|
17
15
|
spec.require_paths = ['lib']
|
18
16
|
spec.files = `git ls-files`.split.reject {|f| f.start_with? 'test', 'spec', 'features'}
|
19
17
|
|
20
|
-
spec.required_ruby_version = '>= 2.
|
18
|
+
spec.required_ruby_version = '>= 2.2'
|
21
19
|
|
22
20
|
spec.add_dependency 'http-2', '~> 0.8', '>= 0.8.4'
|
23
21
|
spec.add_dependency 'colored', '1.2'
|
24
22
|
|
25
|
-
spec.add_development_dependency "bundler", "~> 1.
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.15"
|
26
24
|
spec.add_development_dependency "rake", "~> 10.0"
|
27
25
|
spec.add_development_dependency "minitest", "~> 5.0"
|
28
26
|
end
|
data/lib/h2/client/tcp_socket.rb
CHANGED
@@ -7,13 +7,11 @@ module H2
|
|
7
7
|
DEFAULT_TIMEOUT = 10
|
8
8
|
# ON_LINUX = !!(RUBY_PLATFORM =~ /linux/)
|
9
9
|
|
10
|
-
attr_reader :selector
|
11
|
-
|
12
10
|
def initialize addr, port, timeout = DEFAULT_TIMEOUT
|
13
11
|
|
14
12
|
# resolve name & pack addr
|
15
13
|
family, addr = Socket.getaddrinfo(addr, port, nil, :STREAM, nil, AI_ALL).first.values_at(0,3)
|
16
|
-
|
14
|
+
@_sockaddr = Socket.sockaddr_in port, addr
|
17
15
|
|
18
16
|
super family, SOCK_STREAM
|
19
17
|
|
@@ -23,23 +21,46 @@ module H2
|
|
23
21
|
# cork on linux
|
24
22
|
# setsockopt IPPROTO_TCP, TCP_CORK, 1 if ON_LINUX
|
25
23
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
24
|
+
handle_wait_writable(timeout){ _connect } if _connect == :wait_writable
|
25
|
+
end
|
26
|
+
|
27
|
+
def selector
|
28
|
+
@selector ||= [self]
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def _connect
|
34
|
+
connect_nonblock @_sockaddr
|
35
|
+
rescue IO::WaitWritable
|
36
|
+
:wait_writable
|
37
|
+
end
|
38
|
+
|
39
|
+
def handle_wait_writable timeout, &block
|
40
|
+
if IO.select nil, selector, nil, timeout
|
41
|
+
begin
|
42
|
+
handle_wait_writable(timeout, &block) if yield == :wait_writable
|
43
|
+
rescue Errno::EISCONN
|
44
|
+
rescue
|
36
45
|
close
|
37
|
-
raise
|
46
|
+
raise
|
38
47
|
end
|
48
|
+
else
|
49
|
+
close
|
50
|
+
raise Errno::ETIMEDOUT
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
module ExceptionlessIO
|
55
|
+
|
56
|
+
def _connect
|
57
|
+
connect_nonblock(@_sockaddr, exception: false)
|
39
58
|
end
|
40
59
|
|
41
60
|
end
|
42
61
|
|
62
|
+
prepend ExceptionlessIO if H2.exceptionless_io?
|
63
|
+
|
43
64
|
end
|
44
65
|
end
|
45
66
|
end
|
data/lib/h2/client.rb
CHANGED
@@ -14,7 +14,6 @@ module H2
|
|
14
14
|
:promise
|
15
15
|
]
|
16
16
|
|
17
|
-
ALPN_OPENSSL_MIN_VERSION = 0x10002001
|
18
17
|
ALPN_PROTOCOLS = ['h2']
|
19
18
|
DEFAULT_MAXLEN = 4096
|
20
19
|
RE_IP_ADDR = Regexp.union Resolv::IPv4::Regex, Resolv::IPv6::Regex
|
@@ -131,6 +130,10 @@ module H2
|
|
131
130
|
|
132
131
|
# ---
|
133
132
|
|
133
|
+
def selector
|
134
|
+
@selector ||= [@socket]
|
135
|
+
end
|
136
|
+
|
134
137
|
def read maxlen = DEFAULT_MAXLEN
|
135
138
|
main = Thread.current
|
136
139
|
@reader = Thread.new do
|
@@ -145,10 +148,9 @@ module H2
|
|
145
148
|
def _read maxlen = DEFAULT_MAXLEN
|
146
149
|
begin
|
147
150
|
data = nil
|
148
|
-
selector = [@socket]
|
149
151
|
|
150
152
|
loop do
|
151
|
-
data =
|
153
|
+
data = read_from_socket maxlen
|
152
154
|
case data
|
153
155
|
when :wait_readable
|
154
156
|
IO.select selector
|
@@ -171,6 +173,12 @@ module H2
|
|
171
173
|
end
|
172
174
|
end
|
173
175
|
|
176
|
+
def read_from_socket maxlen
|
177
|
+
@socket.read_nonblock maxlen
|
178
|
+
rescue IO::WaitReadable
|
179
|
+
:wait_readable
|
180
|
+
end
|
181
|
+
|
174
182
|
# ---
|
175
183
|
|
176
184
|
def on_close
|
@@ -184,7 +192,7 @@ module H2
|
|
184
192
|
if ::H2::Client::TCPSocket === @socket
|
185
193
|
total = bytes.bytesize
|
186
194
|
loop do
|
187
|
-
n =
|
195
|
+
n = write_to_socket bytes
|
188
196
|
if n == :wait_writable
|
189
197
|
IO.select nil, @socket.selector
|
190
198
|
elsif n < total
|
@@ -199,6 +207,12 @@ module H2
|
|
199
207
|
@socket.flush
|
200
208
|
end
|
201
209
|
|
210
|
+
def write_to_socket bytes
|
211
|
+
@socket.write_nonblock bytes
|
212
|
+
rescue IO::WaitWritable
|
213
|
+
:wait_writable
|
214
|
+
end
|
215
|
+
|
202
216
|
def on_goaway *args
|
203
217
|
on :goaway, *args
|
204
218
|
close
|
@@ -240,11 +254,14 @@ module H2
|
|
240
254
|
ctx.ssl_version = :TLSv1_2
|
241
255
|
ctx.verify_mode = @tls[:verify_mode] || ( OpenSSL::SSL::VERIFY_PEER |
|
242
256
|
OpenSSL::SSL::VERIFY_FAIL_IF_NO_PEER_CERT )
|
243
|
-
|
257
|
+
|
258
|
+
# https://github.com/jruby/jruby-openssl/issues/99
|
259
|
+
set_ssl_context_protocols ctx unless H2.jruby?
|
260
|
+
|
244
261
|
ctx
|
245
262
|
end
|
246
263
|
|
247
|
-
if
|
264
|
+
if H2.alpn?
|
248
265
|
def set_ssl_context_protocols ctx
|
249
266
|
ctx.alpn_protocols = ALPN_PROTOCOLS
|
250
267
|
end
|
@@ -254,5 +271,21 @@ module H2
|
|
254
271
|
end
|
255
272
|
end
|
256
273
|
|
274
|
+
# ---
|
275
|
+
|
276
|
+
module ExceptionlessIO
|
277
|
+
|
278
|
+
def read_from_socket maxlen
|
279
|
+
@socket.read_nonblock maxlen, exception: false
|
280
|
+
end
|
281
|
+
|
282
|
+
def write_to_socket bytes
|
283
|
+
@socket.write_nonblock bytes, exception: false
|
284
|
+
end
|
285
|
+
|
286
|
+
end
|
287
|
+
|
288
|
+
prepend ExceptionlessIO if H2.exceptionless_io?
|
289
|
+
|
257
290
|
end
|
258
291
|
end
|
data/lib/h2/version.rb
CHANGED
@@ -1,3 +1,23 @@
|
|
1
1
|
module H2
|
2
|
-
VERSION = '0.
|
2
|
+
VERSION = '0.4.0'
|
3
|
+
|
4
|
+
class << self
|
5
|
+
|
6
|
+
ALPN_OPENSSL_MIN_VERSION = 0x10002001
|
7
|
+
|
8
|
+
def alpn?
|
9
|
+
exceptionless_io? && OpenSSL::OPENSSL_VERSION_NUMBER >= ALPN_OPENSSL_MIN_VERSION
|
10
|
+
end
|
11
|
+
|
12
|
+
def exceptionless_io?
|
13
|
+
RUBY_VERSION >= '2.3' && !jruby?
|
14
|
+
end
|
15
|
+
|
16
|
+
def jruby?
|
17
|
+
return @jruby if defined? @jruby
|
18
|
+
@jruby = RUBY_ENGINE == 'jruby'
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
|
3
23
|
end
|
data/lib/h2.rb
CHANGED
@@ -2,7 +2,6 @@
|
|
2
2
|
|
3
3
|
require 'http/2'
|
4
4
|
require 'uri'
|
5
|
-
|
6
5
|
require 'h2/version'
|
7
6
|
|
8
7
|
module H2
|
@@ -87,9 +86,14 @@ module H2
|
|
87
86
|
|
88
87
|
def on event, *args, &block
|
89
88
|
@on ||= {}
|
90
|
-
|
91
|
-
|
92
|
-
|
89
|
+
event_handler = @on[event]
|
90
|
+
if block_given?
|
91
|
+
@on[event] = block
|
92
|
+
self
|
93
|
+
else
|
94
|
+
return if event_handler.nil?
|
95
|
+
return event_handler.call(*args)
|
96
|
+
end
|
93
97
|
end
|
94
98
|
|
95
99
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: h2
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Kenichi Nakamura
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-08-31 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: http-2
|
@@ -50,14 +50,14 @@ dependencies:
|
|
50
50
|
requirements:
|
51
51
|
- - "~>"
|
52
52
|
- !ruby/object:Gem::Version
|
53
|
-
version: '1.
|
53
|
+
version: '1.15'
|
54
54
|
type: :development
|
55
55
|
prerelease: false
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: '1.
|
60
|
+
version: '1.15'
|
61
61
|
- !ruby/object:Gem::Dependency
|
62
62
|
name: rake
|
63
63
|
requirement: !ruby/object:Gem::Requirement
|
@@ -86,7 +86,7 @@ dependencies:
|
|
86
86
|
- - "~>"
|
87
87
|
- !ruby/object:Gem::Version
|
88
88
|
version: '5.0'
|
89
|
-
description: a pure ruby http/2 client based on http-2 for ruby 2.
|
89
|
+
description: a pure ruby http/2 client based on http-2 for ruby 2.2 and above
|
90
90
|
email:
|
91
91
|
- kenichi.nakamura@gmail.com
|
92
92
|
executables:
|
@@ -99,6 +99,7 @@ files:
|
|
99
99
|
- CHANGELOG.md
|
100
100
|
- CODE_OF_CONDUCT.md
|
101
101
|
- Gemfile
|
102
|
+
- Guardfile
|
102
103
|
- LICENSE.txt
|
103
104
|
- README.md
|
104
105
|
- Rakefile
|
@@ -124,7 +125,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
124
125
|
requirements:
|
125
126
|
- - ">="
|
126
127
|
- !ruby/object:Gem::Version
|
127
|
-
version: '2.
|
128
|
+
version: '2.2'
|
128
129
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
129
130
|
requirements:
|
130
131
|
- - ">="
|