async-io 1.8.5 → 1.9.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d5af912a19bd43e7d4c48af0a6835e730ae2dc1755a2454a4e9b35c46cffbd88
4
- data.tar.gz: f660b9e73b7508611bda24f3e68fcc4990da4560d16acce7b8ed0e70fc607e2a
3
+ metadata.gz: 40749911979345a67bd35510958c91ca57fc35ba853b09dfcc283e243f2bf835
4
+ data.tar.gz: 941e9b6d3dd0dfbda32e01dddef808331923b6fbc5851fcddae24a76f065462d
5
5
  SHA512:
6
- metadata.gz: 61f47c817d26b85353da538952e01bd0884c42b385fa4eaff26d1666e411d44e46567ceea49aa3510e3706b03370a9a9fda35a928b1119557e4829a12db4a791
7
- data.tar.gz: e429a7a262b6e6824667e9d7f68c2c29f5ddb385d3d5b95301d3bbbb8a2f918300929a804bcc5493fa18ab51c2fc58707f075c0ae902f5b8d96c96809e0ebd67
6
+ metadata.gz: ce87c35d646cd58a8db777ddb3a9fd5699689769165fb2c09174ee008b29c5e3974e1960c0f26ab4a58f7dcc104e4f270d0bedb800e762092397e1401c326df6
7
+ data.tar.gz: a3b67e9abd2337efcd999f28b8d919faa959e91b686c6dc55474c36cc66dffdf73a154c6e968786f52d44f6e7563aa9b6216169b0a0d0e7e528ceb0eaa435064
data/.travis.yml CHANGED
@@ -10,7 +10,6 @@ before_script:
10
10
 
11
11
  matrix:
12
12
  include:
13
- - rvm: 2.2
14
13
  - rvm: 2.3
15
14
  - rvm: 2.4
16
15
  - rvm: 2.5
data/lib/async/io.rb CHANGED
@@ -22,5 +22,7 @@ require 'async'
22
22
 
23
23
  require_relative "io/generic"
24
24
  require_relative "io/socket"
25
- require_relative "io/endpoint"
26
25
  require_relative "io/version"
26
+
27
+ require_relative "io/endpoint"
28
+ require_relative "io/endpoint/each"
@@ -0,0 +1,56 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'endpoint'
22
+
23
+ module Async
24
+ module IO
25
+ # This class will open and close the socket automatically.
26
+ class AddressEndpoint < Endpoint
27
+ def initialize(address, **options)
28
+ super(**options)
29
+
30
+ @address = address
31
+ @options = options
32
+ end
33
+
34
+ def to_s
35
+ "\#<#{self.class} #{@address.inspect}>"
36
+ end
37
+
38
+ attr :address
39
+ attr :options
40
+
41
+ def bind(&block)
42
+ Socket.bind(@address, **@options, &block)
43
+ end
44
+
45
+ def connect(&block)
46
+ Socket.connect(@address, **@options, &block)
47
+ end
48
+ end
49
+
50
+ class Endpoint
51
+ def self.unix(*args, **options)
52
+ AddressEndpoint.new(Address.unix(*args), **options)
53
+ end
54
+ end
55
+ end
56
+ end
@@ -20,6 +20,7 @@
20
20
 
21
21
  require_relative 'address'
22
22
  require_relative 'socket'
23
+
23
24
  require 'uri'
24
25
 
25
26
  module Async
@@ -35,58 +36,6 @@ module Async
35
36
  @options[:hostname]
36
37
  end
37
38
 
38
- def self.parse(string, **options)
39
- uri = URI.parse(string)
40
-
41
- self.send(uri.scheme, uri.host, uri.port, **options)
42
- end
43
-
44
- # args: nodename, service, family, socktype, protocol, flags
45
- def self.tcp(*args, **options)
46
- args[3] = ::Socket::SOCK_STREAM
47
-
48
- HostEndpoint.new(args, **options)
49
- end
50
-
51
- def self.udp(*args, **options)
52
- args[3] = ::Socket::SOCK_DGRAM
53
-
54
- HostEndpoint.new(args, **options)
55
- end
56
-
57
- def self.unix(*args, **options)
58
- AddressEndpoint.new(Address.unix(*args), **options)
59
- end
60
-
61
- def self.ssl(*args, **options)
62
- SecureEndpoint.new(self.tcp(*args, **options), **options)
63
- end
64
-
65
- def self.try_convert(specification)
66
- if specification.is_a? self
67
- specification
68
- elsif specification.is_a? Array
69
- self.send(*specification)
70
- elsif specification.is_a? String
71
- self.parse(specification)
72
- elsif specification.is_a? ::BasicSocket
73
- SocketEndpoint.new(specification)
74
- elsif specification.is_a? Generic
75
- Endpoint.new(specification)
76
- else
77
- raise ArgumentError.new("Not sure how to convert #{specification} to endpoint!")
78
- end
79
- end
80
-
81
- # Generate a list of endpoint from an array.
82
- def self.each(specifications, &block)
83
- return to_enum(:each, specifications) unless block_given?
84
-
85
- specifications.each do |specification|
86
- yield try_convert(specification)
87
- end
88
- end
89
-
90
39
  def each
91
40
  return to_enum unless block_given?
92
41
 
@@ -100,164 +49,11 @@ module Async
100
49
  server.accept_each(&block)
101
50
  end
102
51
  end
103
- end
104
-
105
- class HostEndpoint < Endpoint
106
- def initialize(specification, **options)
107
- super(**options)
108
-
109
- @specification = specification
110
- end
111
-
112
- def to_s
113
- "\#<#{self.class} #{@specification.inspect}>"
114
- end
115
-
116
- def hostname
117
- @specification.first
118
- end
119
-
120
- def connect(&block)
121
- last_error = nil
122
-
123
- Addrinfo.foreach(*@specification).each do |address|
124
- begin
125
- return Socket.connect(address, **@options, &block)
126
- rescue
127
- last_error = $!
128
- end
129
- end
130
-
131
- raise last_error
132
- end
133
-
134
- def bind(&block)
135
- Addrinfo.foreach(*@specification) do |address|
136
- Socket.bind(address, **@options, &block)
137
- end
138
- end
139
-
140
- def each
141
- return to_enum unless block_given?
142
-
143
- Addrinfo.foreach(*@specification).each do |address|
144
- yield AddressEndpoint.new(address, **@options)
145
- end
146
- end
147
- end
148
-
149
- # This class will open and close the socket automatically.
150
- class AddressEndpoint < Endpoint
151
- def initialize(address, **options)
152
- super(**options)
153
-
154
- @address = address
155
- @options = options
156
- end
157
-
158
- def to_s
159
- "\#<#{self.class} #{@address.inspect}>"
160
- end
161
-
162
- attr :address
163
- attr :options
164
-
165
- def bind(&block)
166
- Socket.bind(@address, **@options, &block)
167
- end
168
-
169
- def connect(&block)
170
- Socket.connect(@address, **@options, &block)
171
- end
172
- end
173
-
174
- class SecureEndpoint < Endpoint
175
- def initialize(endpoint, **options)
176
- super(**options)
177
-
178
- @endpoint = endpoint
179
- end
180
-
181
- def to_s
182
- "\#<#{self.class} #{@endpoint}>"
183
- end
184
-
185
- def hostname
186
- @options.fetch(:hostname) {@endpoint.hostname}
187
- end
188
-
189
- attr :endpoint
190
- attr :options
191
-
192
- def params
193
- @options[:ssl_params]
194
- end
195
-
196
- def context
197
- if context = @options[:ssl_context]
198
- if params = self.params
199
- context = context.dup
200
- context.set_params(params)
201
- end
202
- else
203
- context = ::OpenSSL::SSL::SSLContext.new
204
-
205
- if params = self.params
206
- context.set_params(params)
207
- end
208
- end
209
-
210
- return context
211
- end
212
-
213
- def bind
214
- @endpoint.bind do |server|
215
- yield SSLServer.new(server, context)
216
- end
217
- end
218
-
219
- def connect(&block)
220
- SSLSocket.connect(@endpoint.connect, context, hostname, &block)
221
- end
222
52
 
223
- def each
224
- return to_enum unless block_given?
225
-
226
- @endpoint.each do |endpoint|
227
- yield self.class.new(endpoint, @options)
228
- end
229
- end
230
- end
231
-
232
- # This class doesn't exert ownership over the specified socket, wraps a native ::IO.
233
- class SocketEndpoint < Endpoint
234
- def initialize(socket, **options)
235
- super(**options)
53
+ def self.parse(string, **options)
54
+ uri = URI.parse(string)
236
55
 
237
- # This socket should already be in the required state.
238
- @socket = Async::IO.try_convert(socket)
239
- end
240
-
241
- def to_s
242
- "\#<#{self.class} #{@socket.inspect}>"
243
- end
244
-
245
- attr :socket
246
-
247
- def bind(&block)
248
- if block_given?
249
- yield @socket
250
- else
251
- return @socket
252
- end
253
- end
254
-
255
- def connect(&block)
256
- if block_given?
257
- yield @socket
258
- else
259
- return @socket
260
- end
56
+ self.send(uri.scheme, uri.host, uri.port, **options)
261
57
  end
262
58
  end
263
59
  end
@@ -0,0 +1,54 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative "../host_endpoint"
22
+ require_relative "../socket_endpoint"
23
+ require_relative "../ssl_endpoint"
24
+
25
+ module Async
26
+ module IO
27
+ class Endpoint
28
+ def self.try_convert(specification)
29
+ if specification.is_a? self
30
+ specification
31
+ elsif specification.is_a? Array
32
+ self.send(*specification)
33
+ elsif specification.is_a? String
34
+ self.parse(specification)
35
+ elsif specification.is_a? ::BasicSocket
36
+ self.socket(specification)
37
+ elsif specification.is_a? Generic
38
+ self.new(specification)
39
+ else
40
+ raise ArgumentError.new("Not sure how to convert #{specification} to endpoint!")
41
+ end
42
+ end
43
+
44
+ # Generate a list of endpoint from an array.
45
+ def self.each(specifications, &block)
46
+ return to_enum(:each, specifications) unless block_given?
47
+
48
+ specifications.each do |specification|
49
+ yield try_convert(specification)
50
+ end
51
+ end
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,84 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'address_endpoint'
22
+
23
+ module Async
24
+ module IO
25
+ class HostEndpoint < Endpoint
26
+ def initialize(specification, **options)
27
+ super(**options)
28
+
29
+ @specification = specification
30
+ end
31
+
32
+ def to_s
33
+ "\#<#{self.class} #{@specification.inspect}>"
34
+ end
35
+
36
+ def hostname
37
+ @specification.first
38
+ end
39
+
40
+ def connect(&block)
41
+ last_error = nil
42
+
43
+ Addrinfo.foreach(*@specification).each do |address|
44
+ begin
45
+ return Socket.connect(address, **@options, &block)
46
+ rescue
47
+ last_error = $!
48
+ end
49
+ end
50
+
51
+ raise last_error
52
+ end
53
+
54
+ def bind(&block)
55
+ Addrinfo.foreach(*@specification) do |address|
56
+ Socket.bind(address, **@options, &block)
57
+ end
58
+ end
59
+
60
+ def each
61
+ return to_enum unless block_given?
62
+
63
+ Addrinfo.foreach(*@specification).each do |address|
64
+ yield AddressEndpoint.new(address, **@options)
65
+ end
66
+ end
67
+ end
68
+
69
+ class Endpoint
70
+ # args: nodename, service, family, socktype, protocol, flags
71
+ def self.tcp(*args, **options)
72
+ args[3] = ::Socket::SOCK_STREAM
73
+
74
+ HostEndpoint.new(args, **options)
75
+ end
76
+
77
+ def self.udp(*args, **options)
78
+ args[3] = ::Socket::SOCK_DGRAM
79
+
80
+ HostEndpoint.new(args, **options)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,104 @@
1
+ # Copyright, 2018, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'endpoint'
22
+
23
+ module Async
24
+ module IO
25
+ class SharedEndpoint < Endpoint
26
+ def self.bound(endpoint, backlog = Socket::SOMAXCONN)
27
+ wrappers = []
28
+
29
+ endpoint.each do |endpoint|
30
+ server = endpoint.bind
31
+
32
+ server.listen(backlog)
33
+
34
+ server.close_on_exec = false
35
+ server.reactor = nil
36
+
37
+ wrappers << server
38
+ end
39
+
40
+ self.new(endpoint, wrappers)
41
+ end
42
+
43
+ def self.connected(endpoint)
44
+ peer = endpoint.connect
45
+
46
+ peer.close_on_exec = false
47
+ peer.reactor = nil
48
+
49
+ self.new(endpoint, [peer])
50
+ end
51
+
52
+ def initialize(endpoint, wrappers)
53
+ @wrappers = wrappers
54
+ @endpoint = endpoint
55
+ end
56
+
57
+ def bind
58
+ task = Async::Task.current
59
+
60
+ @wrappers.each do |server|
61
+ server = server.dup
62
+
63
+ task.async do |task|
64
+ task.annotate "binding to #{server.inspect}"
65
+
66
+ begin
67
+ yield server, task
68
+ ensure
69
+ server.close
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ def connect
76
+ task = Async::Task.current
77
+
78
+ @wrappers.each do |peer|
79
+ peer = peer.dup
80
+
81
+ task.async do |task|
82
+ task.annotate "connected to #{peer.inspect}"
83
+
84
+ begin
85
+ yield peer, task
86
+ ensure
87
+ peer.close
88
+ end
89
+ end
90
+ end
91
+ end
92
+
93
+ def accept(backlog = nil, &block)
94
+ bind do |server|
95
+ server.accept_each(&block)
96
+ end
97
+ end
98
+
99
+ def inspect
100
+ "\#<#{self.class} #{@endpoint.inspect}>"
101
+ end
102
+ end
103
+ end
104
+ end
@@ -153,7 +153,7 @@ module Async
153
153
 
154
154
  return wrapper unless block_given?
155
155
 
156
- task.async do
156
+ task.async do |task|
157
157
  task.annotate "binding to #{local_address.inspect}"
158
158
 
159
159
  begin
@@ -0,0 +1,67 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'endpoint'
22
+
23
+ module Async
24
+ module IO
25
+ # This class doesn't exert ownership over the specified socket, wraps a native ::IO.
26
+ class SocketEndpoint < Endpoint
27
+ def initialize(socket, **options)
28
+ super(**options)
29
+
30
+ # This socket should already be in the required state.
31
+ @socket = Async::IO.try_convert(socket)
32
+ end
33
+
34
+ def to_s
35
+ "\#<#{self.class} #{@socket.inspect}>"
36
+ end
37
+
38
+ attr :socket
39
+
40
+ def bind(&block)
41
+ if block_given?
42
+ yield @socket
43
+
44
+ @socket.reactor = nil
45
+ else
46
+ return @socket
47
+ end
48
+ end
49
+
50
+ def connect(&block)
51
+ if block_given?
52
+ yield @socket
53
+
54
+ @socket.reactor = nil
55
+ else
56
+ return @socket
57
+ end
58
+ end
59
+ end
60
+
61
+ class Endpoint
62
+ def self.socket(socket, **options)
63
+ SocketEndpoint.new(socket, **options)
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,93 @@
1
+ # Copyright, 2017, by Samuel G. D. Williams. <http://www.codeotaku.com>
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in
11
+ # all copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ # THE SOFTWARE.
20
+
21
+ require_relative 'endpoint'
22
+ require_relative 'ssl_socket'
23
+
24
+ module Async
25
+ module IO
26
+ class SSLEndpoint < Endpoint
27
+ def initialize(endpoint, **options)
28
+ super(**options)
29
+
30
+ @endpoint = endpoint
31
+ end
32
+
33
+ def to_s
34
+ "\#<#{self.class} #{@endpoint}>"
35
+ end
36
+
37
+ def hostname
38
+ @options.fetch(:hostname) {@endpoint.hostname}
39
+ end
40
+
41
+ attr :endpoint
42
+ attr :options
43
+
44
+ def params
45
+ @options[:ssl_params]
46
+ end
47
+
48
+ def context
49
+ if context = @options[:ssl_context]
50
+ if params = self.params
51
+ context = context.dup
52
+ context.set_params(params)
53
+ end
54
+ else
55
+ context = ::OpenSSL::SSL::SSLContext.new
56
+
57
+ if params = self.params
58
+ context.set_params(params)
59
+ end
60
+ end
61
+
62
+ return context
63
+ end
64
+
65
+ def bind
66
+ @endpoint.bind do |server|
67
+ yield SSLServer.new(server, context)
68
+ end
69
+ end
70
+
71
+ def connect(&block)
72
+ SSLSocket.connect(@endpoint.connect, context, hostname, &block)
73
+ end
74
+
75
+ def each
76
+ return to_enum unless block_given?
77
+
78
+ @endpoint.each do |endpoint|
79
+ yield self.class.new(endpoint, @options)
80
+ end
81
+ end
82
+ end
83
+
84
+ # Backwards compatibility.
85
+ SecureEndpoint = SSLEndpoint
86
+
87
+ class Endpoint
88
+ def self.ssl(*args, **options)
89
+ SSLEndpoint.new(self.tcp(*args, **options), **options)
90
+ end
91
+ end
92
+ end
93
+ end
@@ -20,6 +20,6 @@
20
20
 
21
21
  module Async
22
22
  module IO
23
- VERSION = "1.8.5"
23
+ VERSION = "1.9.2"
24
24
  end
25
25
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: async-io
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.8.5
4
+ version: 1.9.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Samuel Williams
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-04-29 00:00:00.000000000 Z
11
+ date: 2018-04-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: async
@@ -97,12 +97,18 @@ files:
97
97
  - examples/broken_ssl.rb
98
98
  - lib/async/io.rb
99
99
  - lib/async/io/address.rb
100
+ - lib/async/io/address_endpoint.rb
100
101
  - lib/async/io/binary_string.rb
101
102
  - lib/async/io/endpoint.rb
103
+ - lib/async/io/endpoint/each.rb
102
104
  - lib/async/io/generic.rb
105
+ - lib/async/io/host_endpoint.rb
103
106
  - lib/async/io/notification.rb
104
107
  - lib/async/io/protocol/line.rb
108
+ - lib/async/io/shared_endpoint.rb
105
109
  - lib/async/io/socket.rb
110
+ - lib/async/io/socket_endpoint.rb
111
+ - lib/async/io/ssl_endpoint.rb
106
112
  - lib/async/io/ssl_socket.rb
107
113
  - lib/async/io/standard.rb
108
114
  - lib/async/io/stream.rb