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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: dfd3251c0bd00b269688a2e87b54e009be339aff
4
- data.tar.gz: ec1799dd72604f8e089bd7be923f1f5083ec8c2d
3
+ metadata.gz: 59101b19f83a2994cc9186c11121c95645e5cdf4
4
+ data.tar.gz: fd22e1173757e89c855641daf391e9b55de79204
5
5
  SHA512:
6
- metadata.gz: e99a4e6d24b280b3ca9b60189e067c4382f585723a8aae28185e5e85423d0f2ad11cb5d8758082bc323f51a9fcffbdbaa522c12552d1777d27c37c93994ddb62
7
- data.tar.gz: cb8952f4b441870ee7b8fc3d1dd839c74fd653ce8a7b41eaf1d0c4b0a84fb4eab687c995f2505b1fe3ccaa5fb6134f8739ba8fbad8fbd419f838ef9e0c0ca16b
6
+ metadata.gz: 3431f613af4aea436ae44e2ef3e617408012553bf9d3b5ab36b6d4d0068d46d7485560b02037cb98b6eac7edaa8d07f3b79350e150c57330c4fe8f66c2d8a4be
7
+ data.tar.gz: f8e98e3d6838005d1c83848a35f48166eeb76a06dc87b53b9cf03c7ea6543c7b339285626a9d8de9a4ce90e2d1859babd3b78cd4e2d51f0088541e91f84dcee1
data/.travis.yml CHANGED
@@ -1,9 +1,10 @@
1
1
  sudo: false
2
2
  language: ruby
3
3
  rvm:
4
- - 2.3.0
5
- - 2.3.1
6
- - 2.3.2
7
- - 2.3.3
8
- - 2.4.0
4
+ - 2.2.7
5
+ - 2.3.4
9
6
  - 2.4.1
7
+ - jruby-9.1.12.0
8
+ matrix:
9
+ allow_failures:
10
+ - rvm: jruby-9.1.12.0
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 'pry-byebug'
16
- gem 'reel', require: 'reel/h2', git: 'https://github.com/kenichi/reel', branch: 'h2'
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
@@ -0,0 +1,3 @@
1
+ guard :rake, task: 'test' do
2
+ watch %r{^(lib|test).*}
3
+ end
data/bin/console CHANGED
@@ -4,22 +4,5 @@ require 'bundler/setup'
4
4
  require 'h2'
5
5
  require 'irb'
6
6
 
7
- #Bundler.require :development
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
@@ -66,6 +66,10 @@ OptionParser.new do |o|
66
66
  options[:method] = meth
67
67
  end
68
68
 
69
+ o.on '--version', 'print version information' do
70
+ puts "#{H2::USER_AGENT['user-agent']} using http-2-#{HTTP2::VERSION}"
71
+ exit
72
+ end
69
73
 
70
74
  end.parse!
71
75
 
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.3 and above'
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.3'
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.13"
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
@@ -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
- sockaddr = Socket.sockaddr_in port, addr
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
- if connect_nonblock(sockaddr, exception: false) == :wait_writable
27
- if IO.select nil, [self], nil, timeout
28
- begin
29
- connect_nonblock sockaddr
30
- rescue Errno::EISCONN
31
- rescue
32
- close
33
- raise
34
- end
35
- else
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 Errno::ETIMEDOUT
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 = @socket.read_nonblock maxlen, exception: false
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 = @socket.sendmsg_nonblock bytes, exception: false
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
- set_ssl_context_protocols ctx
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 OpenSSL::OPENSSL_VERSION_NUMBER >= ALPN_OPENSSL_MIN_VERSION
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.3.1'
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
- return @on[event]&.call(*args) unless block_given?
91
- return @on[event] = block if block_given?
92
- self
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.3.1
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-05-13 00:00:00.000000000 Z
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.13'
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.13'
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.3 and above
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.3'
128
+ version: '2.2'
128
129
  required_rubygems_version: !ruby/object:Gem::Requirement
129
130
  requirements:
130
131
  - - ">="