io-endpoint 0.2.0 → 0.3.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
- checksums.yaml.gz.sig +0 -0
- data/lib/io/endpoint/address_endpoint.rb +4 -3
- data/lib/io/endpoint/composite_endpoint.rb +10 -2
- data/lib/io/endpoint/generic.rb +5 -9
- data/lib/io/endpoint/host_endpoint.rb +6 -2
- data/lib/io/endpoint/shared_endpoint.rb +4 -6
- data/lib/io/endpoint/ssl_endpoint.rb +40 -13
- data/lib/io/endpoint/version.rb +1 -1
- data/readme.md +8 -0
- data.tar.gz.sig +0 -0
- metadata +4 -46
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c519269d1e8459a607159be713100765c2e424f199a08cce97e1ba6c877b5b6a
|
4
|
+
data.tar.gz: ee2e142c5320d9412395c80098e669971b8956b43ad58252d52a85e2a97a5a97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 67ce6a415b998cd1d072a1faee146803f30de818666278846cbdf69f8f72fd8c30d0df371ec44747a2ea74a1fdd0d86f100e187ba15d17275ffbb335d29e6df5
|
7
|
+
data.tar.gz: 360a4f1ee5e162e71be467b0090e54eade25f141abde4452f6ba0e389def1398eaabfe5f76aaed4cbf333ba0c40334e014029d7fb76e13d09ff60f428ac63d9f
|
checksums.yaml.gz.sig
CHANGED
Binary file
|
@@ -23,10 +23,11 @@ module IO::Endpoint
|
|
23
23
|
attr :address
|
24
24
|
|
25
25
|
# Bind a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
|
26
|
-
# @yield
|
27
|
-
#
|
26
|
+
# @yield {|socket| ...} An optional block which will be passed the socket.
|
27
|
+
# @parameter socket [Socket] The socket which has been bound.
|
28
|
+
# @return [Array(Socket)] the bound socket
|
28
29
|
def bind(wrapper = Wrapper.default, &block)
|
29
|
-
wrapper.bind(@address, **@options, &block)
|
30
|
+
[wrapper.bind(@address, **@options, &block)]
|
30
31
|
end
|
31
32
|
|
32
33
|
# Connects a socket to the given address. If a block is given, the socket will be automatically closed when the block exits.
|
@@ -13,7 +13,9 @@ module IO::Endpoint
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def each(&block)
|
16
|
-
@endpoints.each
|
16
|
+
@endpoints.each do |endpoint|
|
17
|
+
endpoint.each(&block)
|
18
|
+
end
|
17
19
|
end
|
18
20
|
|
19
21
|
def connect(&block)
|
@@ -30,7 +32,13 @@ module IO::Endpoint
|
|
30
32
|
end
|
31
33
|
|
32
34
|
def bind(&block)
|
33
|
-
|
35
|
+
if block_given?
|
36
|
+
@endpoints.each do |endpoint|
|
37
|
+
endpoint.bind(&block)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@endpoints.map(&:bind).flatten.compact
|
41
|
+
end
|
34
42
|
end
|
35
43
|
end
|
36
44
|
|
data/lib/io/endpoint/generic.rb
CHANGED
@@ -77,13 +77,15 @@ module IO::Endpoint
|
|
77
77
|
socket, address = server.accept
|
78
78
|
|
79
79
|
Fiber.schedule do
|
80
|
-
yield
|
80
|
+
yield socket, address
|
81
81
|
end
|
82
82
|
end
|
83
83
|
end
|
84
84
|
end
|
85
85
|
|
86
|
-
# Create an Endpoint instance by URI scheme. The host and port of the URI will be passed to the Endpoint factory method, along with any options
|
86
|
+
# Create an Endpoint instance by URI scheme. The host and port of the URI will be passed to the Endpoint factory method, along with any options.\
|
87
|
+
#
|
88
|
+
# You should not use untrusted input as it may execute arbitrary code.
|
87
89
|
#
|
88
90
|
# @param string [String] URI as string. Scheme will decide implementation used.
|
89
91
|
# @param options keyword arguments passed through to {#initialize}
|
@@ -95,13 +97,7 @@ module IO::Endpoint
|
|
95
97
|
def self.parse(string, **options)
|
96
98
|
uri = URI.parse(string)
|
97
99
|
|
98
|
-
|
99
|
-
end
|
100
|
-
|
101
|
-
protected
|
102
|
-
|
103
|
-
def accepted(socket)
|
104
|
-
socket
|
100
|
+
IO::Endpoint.public_send(uri.scheme, uri.host, uri.port, **options)
|
105
101
|
end
|
106
102
|
end
|
107
103
|
end
|
@@ -23,7 +23,11 @@ module IO::Endpoint
|
|
23
23
|
attr :specification
|
24
24
|
|
25
25
|
def hostname
|
26
|
-
@specification
|
26
|
+
@specification[0]
|
27
|
+
end
|
28
|
+
|
29
|
+
def service
|
30
|
+
@specification[1]
|
27
31
|
end
|
28
32
|
|
29
33
|
# Try to connect to the given host by connecting to each address in sequence until a connection is made.
|
@@ -35,7 +39,7 @@ module IO::Endpoint
|
|
35
39
|
|
36
40
|
Addrinfo.foreach(*@specification) do |address|
|
37
41
|
begin
|
38
|
-
socket = wrapper.connect(
|
42
|
+
socket = wrapper.connect(address, **@options)
|
39
43
|
rescue Errno::ECONNREFUSED, Errno::ENETUNREACH, Errno::EAGAIN => last_error
|
40
44
|
# Try again unless if possible, otherwise raise...
|
41
45
|
else
|
@@ -7,16 +7,16 @@ require_relative 'generic'
|
|
7
7
|
require_relative 'composite_endpoint'
|
8
8
|
require_relative 'socket_endpoint'
|
9
9
|
|
10
|
+
require 'openssl'
|
11
|
+
|
10
12
|
module IO::Endpoint
|
11
13
|
# Pre-connect and pre-bind sockets so that it can be used between processes.
|
12
14
|
class SharedEndpoint < Generic
|
13
15
|
# Create a new `SharedEndpoint` by binding to the given endpoint.
|
14
16
|
def self.bound(endpoint, backlog: Socket::SOMAXCONN, close_on_exec: false, **options)
|
15
|
-
sockets =
|
17
|
+
sockets = endpoint.bind(**options)
|
16
18
|
|
17
|
-
|
18
|
-
server = server_endpoint.bind(**options)
|
19
|
-
|
19
|
+
sockets.each do |server|
|
20
20
|
# This is somewhat optional. We want to have a generic interface as much as possible so that users of this interface can just call it without knowing a lot of internal details. Therefore, we ignore errors here if it's because the underlying socket does not support the operation.
|
21
21
|
begin
|
22
22
|
server.listen(backlog)
|
@@ -25,8 +25,6 @@ module IO::Endpoint
|
|
25
25
|
end
|
26
26
|
|
27
27
|
server.close_on_exec = close_on_exec
|
28
|
-
|
29
|
-
sockets << server
|
30
28
|
end
|
31
29
|
|
32
30
|
return self.new(endpoint, sockets)
|
@@ -8,6 +8,38 @@ require_relative 'generic'
|
|
8
8
|
|
9
9
|
require 'openssl'
|
10
10
|
|
11
|
+
module OpenSSL::SSL::SocketForwarder
|
12
|
+
unless method_defined?(:close_on_exec=)
|
13
|
+
def close_on_exec=(value)
|
14
|
+
to_io.close_on_exec = value
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
unless method_defined?(:close_on_exec)
|
19
|
+
def local_address
|
20
|
+
to_io.local_address
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
unless method_defined?(:wait)
|
25
|
+
def wait(*arguments)
|
26
|
+
to_io.wait(*arguments)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
unless method_defined?(:wait_readable)
|
31
|
+
def wait_readable(*arguments)
|
32
|
+
to_io.wait_readable(*arguments)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
unless method_defined?(:wait_writable)
|
37
|
+
def wait_writable(*arguments)
|
38
|
+
to_io.wait_writable(*arguments)
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
11
43
|
module IO::Endpoint
|
12
44
|
class SSLEndpoint < Generic
|
13
45
|
def initialize(endpoint, **options)
|
@@ -41,13 +73,13 @@ module IO::Endpoint
|
|
41
73
|
@options[:ssl_params]
|
42
74
|
end
|
43
75
|
|
44
|
-
def build_context(context = OpenSSL::SSL::SSLContext.new)
|
76
|
+
def build_context(context = ::OpenSSL::SSL::SSLContext.new)
|
45
77
|
if params = self.params
|
46
78
|
context.set_params(params)
|
47
79
|
end
|
48
80
|
|
49
|
-
context.setup
|
50
|
-
context.freeze
|
81
|
+
# context.setup
|
82
|
+
# context.freeze
|
51
83
|
|
52
84
|
return context
|
53
85
|
end
|
@@ -62,10 +94,12 @@ module IO::Endpoint
|
|
62
94
|
def bind
|
63
95
|
if block_given?
|
64
96
|
@endpoint.bind do |server|
|
65
|
-
yield OpenSSL::SSL::SSLServer.new(server, context)
|
97
|
+
yield ::OpenSSL::SSL::SSLServer.new(server, context)
|
66
98
|
end
|
67
99
|
else
|
68
|
-
|
100
|
+
@endpoint.bind.map do |server|
|
101
|
+
::OpenSSL::SSL::SSLServer.new(server, context)
|
102
|
+
end
|
69
103
|
end
|
70
104
|
end
|
71
105
|
|
@@ -73,7 +107,7 @@ module IO::Endpoint
|
|
73
107
|
# @yield [Socket] the socket which is being connected
|
74
108
|
# @return [Socket] the connected socket
|
75
109
|
def connect(&block)
|
76
|
-
socket = OpenSSL::SSL::SSLSocket.new(@endpoint.connect, context)
|
110
|
+
socket = ::OpenSSL::SSL::SSLSocket.new(@endpoint.connect, context)
|
77
111
|
|
78
112
|
if hostname = self.hostname
|
79
113
|
socket.hostname = hostname
|
@@ -102,13 +136,6 @@ module IO::Endpoint
|
|
102
136
|
yield self.class.new(endpoint, **@options)
|
103
137
|
end
|
104
138
|
end
|
105
|
-
|
106
|
-
protected
|
107
|
-
|
108
|
-
def accepted(socket)
|
109
|
-
socket.accept
|
110
|
-
socket
|
111
|
-
end
|
112
139
|
end
|
113
140
|
|
114
141
|
# @param arguments
|
data/lib/io/endpoint/version.rb
CHANGED
data/readme.md
CHANGED
@@ -18,6 +18,14 @@ We welcome contributions to this project.
|
|
18
18
|
4. Push to the branch (`git push origin my-new-feature`).
|
19
19
|
5. Create new Pull Request.
|
20
20
|
|
21
|
+
### Developer Certificate of Origin
|
22
|
+
|
23
|
+
This project uses the [Developer Certificate of Origin](https://developercertificate.org/). All contributors to this project must agree to this document to have their contributions accepted.
|
24
|
+
|
25
|
+
### Contributor Covenant
|
26
|
+
|
27
|
+
This project is governed by the [Contributor Covenant](https://www.contributor-covenant.org/). All contributors and participants agree to abide by its terms.
|
28
|
+
|
21
29
|
## See Also
|
22
30
|
|
23
31
|
- [async-io](https://github.com/socketry/async-io) — Asynchronous IO primitives.
|
data.tar.gz.sig
CHANGED
Binary file
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: io-endpoint
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Samuel Williams
|
@@ -37,50 +37,8 @@ cert_chain:
|
|
37
37
|
Q2K9NVun/S785AP05vKkXZEFYxqG6EW012U4oLcFl5MySFajYXRYbuUpH6AY+HP8
|
38
38
|
voD0MPg1DssDLKwXyt1eKD/+Fq0bFWhwVM/1XiAXL7lyYUyOq24KHgQ2Csg=
|
39
39
|
-----END CERTIFICATE-----
|
40
|
-
date: 2023-12-
|
41
|
-
dependencies:
|
42
|
-
- !ruby/object:Gem::Dependency
|
43
|
-
name: bake
|
44
|
-
requirement: !ruby/object:Gem::Requirement
|
45
|
-
requirements:
|
46
|
-
- - ">="
|
47
|
-
- !ruby/object:Gem::Version
|
48
|
-
version: '0'
|
49
|
-
type: :development
|
50
|
-
prerelease: false
|
51
|
-
version_requirements: !ruby/object:Gem::Requirement
|
52
|
-
requirements:
|
53
|
-
- - ">="
|
54
|
-
- !ruby/object:Gem::Version
|
55
|
-
version: '0'
|
56
|
-
- !ruby/object:Gem::Dependency
|
57
|
-
name: covered
|
58
|
-
requirement: !ruby/object:Gem::Requirement
|
59
|
-
requirements:
|
60
|
-
- - ">="
|
61
|
-
- !ruby/object:Gem::Version
|
62
|
-
version: '0'
|
63
|
-
type: :development
|
64
|
-
prerelease: false
|
65
|
-
version_requirements: !ruby/object:Gem::Requirement
|
66
|
-
requirements:
|
67
|
-
- - ">="
|
68
|
-
- !ruby/object:Gem::Version
|
69
|
-
version: '0'
|
70
|
-
- !ruby/object:Gem::Dependency
|
71
|
-
name: sus
|
72
|
-
requirement: !ruby/object:Gem::Requirement
|
73
|
-
requirements:
|
74
|
-
- - ">="
|
75
|
-
- !ruby/object:Gem::Version
|
76
|
-
version: '0'
|
77
|
-
type: :development
|
78
|
-
prerelease: false
|
79
|
-
version_requirements: !ruby/object:Gem::Requirement
|
80
|
-
requirements:
|
81
|
-
- - ">="
|
82
|
-
- !ruby/object:Gem::Version
|
83
|
-
version: '0'
|
40
|
+
date: 2023-12-28 00:00:00.000000000 Z
|
41
|
+
dependencies: []
|
84
42
|
description:
|
85
43
|
email:
|
86
44
|
executables: []
|
@@ -120,7 +78,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
120
78
|
- !ruby/object:Gem::Version
|
121
79
|
version: '0'
|
122
80
|
requirements: []
|
123
|
-
rubygems_version: 3.
|
81
|
+
rubygems_version: 3.5.3
|
124
82
|
signing_key:
|
125
83
|
specification_version: 4
|
126
84
|
summary: Provides a separation of concerns interface for IO endpoints.
|
metadata.gz.sig
CHANGED
Binary file
|