net-http2 0.14.1 → 0.15.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: 7ca19f3b01ed565929287e4db629d7c5a3c1522e
4
- data.tar.gz: d31dc0fc2f7cf652dcc8bdac6fcc8b31b6721797
3
+ metadata.gz: 1d1bbb7eb0d7324fb63a671d0f8fbc2075b6a625
4
+ data.tar.gz: 9d4dd0e9e5131ac605292030235b9a68a8087b83
5
5
  SHA512:
6
- metadata.gz: b0b94a8d7e38e0fed916585ff63b8f1686e0cf0ae0107dced66a7de8199155ac62484366fd1808ba2bfeb5e6fc02fb2bcd4cabab061ecfa2833a6bf1621ef22b
7
- data.tar.gz: f88d758b5174c933832c003ce996f0a97277bf0b24da7ba517825bcb2eb4a898b8773f56b008fe256eb247ca0a659117a8cc04be0f22f463145e60fb414ab117
6
+ metadata.gz: 1db0898b540554278ee5a3789bafae4aac29e9a8075fdfbd26c0aca57f360136b9c3c4c60f57b0ff412030ad87c2878b5890f4e9df255535a73ddf7535609ef4
7
+ data.tar.gz: 064cdc09d94dbd1e13623ae2a42b5cb5f695344f83ed60faadfab7aa1e9f7c721099e8fc8187133f9cbb36523f89142a1672c6071b8bf937b9ca342c954d4ada
data/README.md CHANGED
@@ -95,6 +95,16 @@ client.close
95
95
  NetHttp2::Client.new("https://nghttp2.org", ssl_context: ctx)
96
96
  ```
97
97
 
98
+ * **on(event, &block)**
99
+
100
+ Allows to set a callback for the client. The only available event is `:error`, which allows to set a callback when an error is raised at socket level, hence in the underlying socket thread.
101
+
102
+ ```ruby
103
+ client.on(:error) { |exception| puts "Exception has been raised: #{exception}" }
104
+ ```
105
+
106
+ > It is RECOMMENDED to set the `:error` callback: if none is defined, the underlying socket thread may raise an error in the main thread at unexpected execution times.
107
+
98
108
  * **uri** → **`URI`**
99
109
 
100
110
  Returns the URI of the endpoint.
@@ -202,7 +212,10 @@ The real benefit of HTTP/2 is being able to receive body and header streams. Ins
202
212
 
203
213
 
204
214
  ## Thread-Safety
205
- NetHttp2 is thread-safe.
215
+ NetHttp2 is thread-safe. However, some caution is imperative:
216
+
217
+ * The async callbacks will be executed in a different thread, so ensure that your code in the callbacks is thread-safe.
218
+ * Errors in the underlying socket loop thread will be raised in the main thread at unexpected execution times, unless you specify the `:error` callback on the Client (recommended).
206
219
 
207
220
  ## Contributing
208
221
  So you want to contribute? That's great! Please follow the guidelines below. It will make it easier to get merged in.
@@ -0,0 +1,49 @@
1
+ require 'http/2/connection'
2
+
3
+ # We are currently locked to using the Http2 library v0.8.2 since v0.8.3 still has some compatibility issues:
4
+ # <https://github.com/igrigorik/http-2/issues/92>
5
+ #
6
+ # However, v0.8.2 had a memory leak that was reported in the following issues:
7
+ # <https://github.com/igrigorik/http-2/issues/73>
8
+ # <https://github.com/ostinelli/net-http2/issues/7>
9
+ #
10
+ # Hence, this is a temporary monkey-patch to the HTTP2 library in order to solve the mentioned leak
11
+ # while waiting to fix the issues on v0.8.3.
12
+
13
+ module HTTP2
14
+
15
+ class Connection
16
+
17
+ private
18
+
19
+ def activate_stream(id: nil, **args)
20
+ connection_error(msg: 'Stream ID already exists') if @streams.key?(id)
21
+
22
+ stream = Stream.new({ connection: self, id: id }.merge(args))
23
+
24
+ # Streams that are in the "open" state, or either of the "half closed"
25
+ # states count toward the maximum number of streams that an endpoint is
26
+ # permitted to open.
27
+ stream.once(:active) { @active_stream_count += 1 }
28
+
29
+ @streams_recently_closed ||= {}
30
+ stream.once(:close) do
31
+ @active_stream_count -= 1
32
+
33
+ @streams_recently_closed.delete_if do |closed_stream_id, v|
34
+ to_be_deleted = (Time.now - v) > 15
35
+ @streams.delete(closed_stream_id) if to_be_deleted
36
+ to_be_deleted
37
+ end
38
+
39
+ @streams_recently_closed[id] = Time.now
40
+ end
41
+
42
+ stream.on(:promise, &method(:promise)) if self.is_a? Server
43
+ stream.on(:frame, &method(:send))
44
+ stream.on(:window_update, &method(:window_update))
45
+
46
+ @streams[id] = stream
47
+ end
48
+ end
49
+ end
data/lib/net-http2.rb CHANGED
@@ -1,3 +1,4 @@
1
+ require 'net-http2/callbacks'
1
2
  require 'net-http2/client'
2
3
  require 'net-http2/response'
3
4
  require 'net-http2/request'
@@ -5,6 +6,8 @@ require 'net-http2/socket'
5
6
  require 'net-http2/stream'
6
7
  require 'net-http2/version'
7
8
 
9
+ require 'http2_patch'
10
+
8
11
  module NetHttp2
9
12
  raise "Cannot require NetHttp2, unsupported engine '#{RUBY_ENGINE}'" unless RUBY_ENGINE == "ruby"
10
13
  end
@@ -0,0 +1,22 @@
1
+ module NetHttp2
2
+
3
+ module Callbacks
4
+
5
+ def on(event, &block)
6
+ raise ArgumentError, 'on event must provide a block' unless block_given?
7
+
8
+ @callback_events ||= {}
9
+ @callback_events[event] ||= []
10
+ @callback_events[event] << block
11
+ end
12
+
13
+ def emit(event, arg)
14
+ return unless @callback_events && @callback_events[event]
15
+ @callback_events[event].each { |b| b.call(arg) }
16
+ end
17
+
18
+ def callback_events
19
+ @callback_events || {}
20
+ end
21
+ end
22
+ end
@@ -9,6 +9,9 @@ module NetHttp2
9
9
  PROXY_SETTINGS_KEYS = [:proxy_addr, :proxy_port, :proxy_user, :proxy_pass]
10
10
 
11
11
  class Client
12
+
13
+ include Callbacks
14
+
12
15
  attr_reader :uri
13
16
 
14
17
  def initialize(url, options={})
@@ -101,17 +104,25 @@ module NetHttp2
101
104
  rescue EOFError
102
105
  # socket closed
103
106
  init_vars
104
- raise SocketError.new 'Socket was remotely closed'
107
+ callback_or_raise SocketError.new('Socket was remotely closed')
105
108
 
106
109
  rescue Exception => e
107
110
  # error on socket
108
111
  init_vars
109
- raise e
112
+ callback_or_raise e
110
113
  end
111
114
  end.tap { |t| t.abort_on_exception = true }
112
115
  end
113
116
  end
114
117
 
118
+ def callback_or_raise(exception)
119
+ if callback_events.keys.include?(:error)
120
+ emit(:error, exception)
121
+ else
122
+ raise exception
123
+ end
124
+ end
125
+
115
126
  def socket_loop
116
127
 
117
128
  ensure_sent_before_receiving
@@ -4,6 +4,8 @@ module NetHttp2
4
4
 
5
5
  class Request
6
6
 
7
+ include Callbacks
8
+
7
9
  DEFAULT_TIMEOUT = 60
8
10
 
9
11
  attr_reader :method, :uri, :path, :params, :body, :timeout
@@ -30,11 +32,13 @@ module NetHttp2
30
32
  @headers.merge!(':authority' => "#{@uri.host}:#{@uri.port}") unless @headers[':authority']
31
33
 
32
34
  if @body
33
- @headers.merge!('content-length' => @body.bytesize.to_s)
35
+ @headers.merge!('content-length' => @body.bytesize)
34
36
  else
35
37
  @headers.delete('content-length')
36
38
  end
37
39
 
40
+ @headers.update(@headers) { |_k, v| v.to_s }
41
+
38
42
  @headers
39
43
  end
40
44
 
@@ -44,18 +48,6 @@ module NetHttp2
44
48
  path
45
49
  end
46
50
 
47
- def on(event, &block)
48
- raise ArgumentError, 'on event must provide a block' unless block_given?
49
-
50
- @events[event] ||= []
51
- @events[event] << block
52
- end
53
-
54
- def emit(event, arg)
55
- return unless @events[event]
56
- @events[event].each { |b| b.call(arg) }
57
- end
58
-
59
51
  private
60
52
 
61
53
  # The to_param and to_query code here below is a free adaptation from the original code in:
@@ -1,3 +1,3 @@
1
1
  module NetHttp2
2
- VERSION = "0.14.1"
2
+ VERSION = '0.15.0'.freeze
3
3
  end
data/net-http2.gemspec CHANGED
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
19
19
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
20
20
  spec.require_paths = ["lib"]
21
21
 
22
- spec.add_dependency "http-2", "~> 0.8.2"
22
+ spec.add_dependency "http-2", "0.8.2"
23
23
 
24
24
  spec.add_development_dependency "bundler", "~> 1.3"
25
25
  spec.add_development_dependency "rake", "~> 10.0"
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-http2
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.14.1
4
+ version: 0.15.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roberto Ostinelli
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-12-30 00:00:00.000000000 Z
11
+ date: 2017-02-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: http-2
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.8.2
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.8.2
27
27
  - !ruby/object:Gem::Dependency
@@ -84,7 +84,9 @@ files:
84
84
  - Rakefile
85
85
  - bin/console
86
86
  - bin/setup
87
+ - lib/http2_patch.rb
87
88
  - lib/net-http2.rb
89
+ - lib/net-http2/callbacks.rb
88
90
  - lib/net-http2/client.rb
89
91
  - lib/net-http2/request.rb
90
92
  - lib/net-http2/response.rb