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 +4 -4
- data/README.md +14 -1
- data/lib/http2_patch.rb +49 -0
- data/lib/net-http2.rb +3 -0
- data/lib/net-http2/callbacks.rb +22 -0
- data/lib/net-http2/client.rb +13 -2
- data/lib/net-http2/request.rb +5 -13
- data/lib/net-http2/version.rb +1 -1
- data/net-http2.gemspec +1 -1
- metadata +6 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1d1bbb7eb0d7324fb63a671d0f8fbc2075b6a625
|
4
|
+
data.tar.gz: 9d4dd0e9e5131ac605292030235b9a68a8087b83
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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.
|
data/lib/http2_patch.rb
ADDED
@@ -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
|
data/lib/net-http2/client.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
data/lib/net-http2/request.rb
CHANGED
@@ -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
|
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:
|
data/lib/net-http2/version.rb
CHANGED
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", "
|
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.
|
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:
|
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
|