h2 0.3.1 → 0.4.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/.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
|
- - ">="
|