rubysl-drb 1.0.0 → 2.0.1

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.
@@ -1,7 +1,5 @@
1
- require 'drb/drb'
2
-
3
1
  module DRb
4
- class DRbObject
2
+ class DRbObject # :nodoc:
5
3
  def ==(other)
6
4
  return false unless DRbObject === other
7
5
  (@ref == other.__drbref) && (@uri == other.__drburi)
@@ -1,19 +1,24 @@
1
1
  =begin
2
2
  external service
3
- Copyright (c) 2000,2002 Masatoshi SEKI
3
+ Copyright (c) 2000,2002 Masatoshi SEKI
4
4
  =end
5
5
 
6
6
  require 'drb/drb'
7
+ require 'monitor'
7
8
 
8
9
  module DRb
9
10
  class ExtServ
11
+ include MonitorMixin
10
12
  include DRbUndumped
11
13
 
12
14
  def initialize(there, name, server=nil)
15
+ super()
13
16
  @server = server || DRb::primary_server
14
17
  @name = name
15
18
  ro = DRbObject.new(nil, there)
16
- @invoker = ro.regist(name, DRbObject.new(self, @server.uri))
19
+ synchronize do
20
+ @invoker = ro.regist(name, DRbObject.new(self, @server.uri))
21
+ end
17
22
  end
18
23
  attr_reader :server
19
24
 
@@ -22,11 +27,13 @@ module DRb
22
27
  end
23
28
 
24
29
  def stop_service
25
- @invoker.unregist(@name)
26
- server = @server
27
- @server = nil
28
- server.stop_service
29
- true
30
+ synchronize do
31
+ @invoker.unregist(@name)
32
+ server = @server
33
+ @server = nil
34
+ server.stop_service
35
+ true
36
+ end
30
37
  end
31
38
 
32
39
  def alive?
@@ -35,6 +42,8 @@ module DRb
35
42
  end
36
43
  end
37
44
 
45
+ # :stopdoc:
46
+
38
47
  if __FILE__ == $0
39
48
  class Foo
40
49
  include DRbUndumped
@@ -1,6 +1,6 @@
1
1
  =begin
2
2
  external service manager
3
- Copyright (c) 2000 Masatoshi SEKI
3
+ Copyright (c) 2000 Masatoshi SEKI
4
4
  =end
5
5
 
6
6
  require 'drb/drb'
@@ -21,7 +21,7 @@ module DRb
21
21
  def self.command=(cmd)
22
22
  @@command = cmd
23
23
  end
24
-
24
+
25
25
  def initialize
26
26
  super()
27
27
  @cond = new_cond
@@ -51,20 +51,20 @@ module DRb
51
51
  end
52
52
  self
53
53
  end
54
-
54
+
55
55
  def unregist(name)
56
56
  synchronize do
57
- @servers.delete(name)
57
+ @servers.delete(name)
58
58
  end
59
59
  end
60
60
 
61
61
  private
62
62
  def invoke_thread
63
63
  Thread.new do
64
- while true
65
- name = @queue.pop
66
- invoke_service_command(name, @@command[name])
67
- end
64
+ while true
65
+ name = @queue.pop
66
+ invoke_service_command(name, @@command[name])
67
+ end
68
68
  end
69
69
  end
70
70
 
@@ -75,15 +75,19 @@ module DRb
75
75
  def invoke_service_command(name, command)
76
76
  raise "invalid command. name: #{name}" unless command
77
77
  synchronize do
78
- return if @servers.include?(name)
79
- @servers[name] = false
78
+ return if @servers.include?(name)
79
+ @servers[name] = false
80
80
  end
81
81
  uri = @uri || DRb.uri
82
- if RUBY_PLATFORM =~ /mswin32/ && /NT/ =~ ENV["OS"]
83
- system(%Q'cmd /c start "ruby" /b #{command} #{uri} #{name}')
82
+ if command.respond_to? :to_ary
83
+ command = command.to_ary + [uri, name]
84
+ pid = spawn(*command)
84
85
  else
85
- system("#{command} #{uri} #{name} &")
86
+ pid = spawn("#{command} #{uri} #{name}")
86
87
  end
88
+ th = Process.detach(pid)
89
+ th[:drb_service] = name
90
+ th
87
91
  end
88
92
  end
89
93
  end
@@ -2,8 +2,36 @@ require 'drb/drb'
2
2
  require 'monitor'
3
3
 
4
4
  module DRb
5
+
6
+ # Gateway id conversion forms a gateway between different DRb protocols or
7
+ # networks.
8
+ #
9
+ # The gateway needs to install this id conversion and create servers for
10
+ # each of the protocols or networks it will be a gateway between. It then
11
+ # needs to create a server that attaches to each of these networks. For
12
+ # example:
13
+ #
14
+ # require 'drb/drb'
15
+ # require 'drb/unix'
16
+ # require 'drb/gw'
17
+ #
18
+ # DRb.install_id_conv DRb::GWIdConv.new
19
+ # gw = DRb::GW.new
20
+ # s1 = DRb::DRbServer.new 'drbunix:/path/to/gateway', gw
21
+ # s2 = DRb::DRbServer.new 'druby://example:10000', gw
22
+ #
23
+ # s1.thread.join
24
+ # s2.thread.join
25
+ #
26
+ # Each client must register services with the gateway, for example:
27
+ #
28
+ # DRb.start_service 'drbunix:', nil # an anonymous server
29
+ # gw = DRbObject.new nil, 'drbunix:/path/to/gateway'
30
+ # gw[:unix] = some_service
31
+ # DRb.thread.join
32
+
5
33
  class GWIdConv < DRbIdConv
6
- def to_obj(ref)
34
+ def to_obj(ref) # :nodoc:
7
35
  if Array === ref && ref[0] == :DRbObject
8
36
  return DRbObject.new_with(ref[1], ref[2])
9
37
  end
@@ -11,19 +39,29 @@ module DRb
11
39
  end
12
40
  end
13
41
 
42
+ # The GW provides a synchronized store for participants in the gateway to
43
+ # communicate.
44
+
14
45
  class GW
15
46
  include MonitorMixin
47
+
48
+ # Creates a new GW
49
+
16
50
  def initialize
17
51
  super()
18
52
  @hash = {}
19
53
  end
20
54
 
55
+ # Retrieves +key+ from the GW
56
+
21
57
  def [](key)
22
58
  synchronize do
23
59
  @hash[key]
24
60
  end
25
61
  end
26
62
 
63
+ # Stores value +v+ at +key+ in the GW
64
+
27
65
  def []=(key, v)
28
66
  synchronize do
29
67
  @hash[key] = v
@@ -31,7 +69,7 @@ module DRb
31
69
  end
32
70
  end
33
71
 
34
- class DRbObject
72
+ class DRbObject # :nodoc:
35
73
  def self._load(s)
36
74
  uri, ref = Marshal.load(s)
37
75
  if DRb.uri == uri
@@ -2,14 +2,14 @@
2
2
 
3
3
  module DRb
4
4
  class DRbServer
5
- module InvokeMethod18Mixin
5
+ module InvokeMethod18Mixin # :nodoc: all
6
6
  def block_yield(x)
7
- if x.size == 1 && x[0].class == Array
8
- x[0] = DRbArray.new(x[0])
9
- end
10
- block_value = @block.call(*x)
7
+ if x.size == 1 && x[0].class == Array
8
+ x[0] = DRbArray.new(x[0])
9
+ end
10
+ @block.call(*x)
11
11
  end
12
-
12
+
13
13
  def perform_with_block
14
14
  @obj.__send__(@msg_id, *@argv) do |*x|
15
15
  jump_error = nil
@@ -1,21 +1,24 @@
1
1
  require 'observer'
2
2
 
3
3
  module DRb
4
+ # The Observable module extended to DRb. See Observable for details.
4
5
  module DRbObservable
5
6
  include Observable
6
7
 
8
+ # Notifies observers of a change in state. See also
9
+ # Observable#notify_observers
7
10
  def notify_observers(*arg)
8
11
  if defined? @observer_state and @observer_state
9
- if defined? @observer_peers
10
- for i in @observer_peers.dup
11
- begin
12
- i.update(*arg)
13
- rescue
14
- delete_observer(i)
15
- end
16
- end
17
- end
18
- @observer_state = false
12
+ if defined? @observer_peers
13
+ @observer_peers.each do |observer, method|
14
+ begin
15
+ observer.send(method, *arg)
16
+ rescue
17
+ delete_observer(observer)
18
+ end
19
+ end
20
+ end
21
+ @observer_state = false
19
22
  end
20
23
  end
21
24
  end
@@ -5,124 +5,248 @@ require 'singleton'
5
5
 
6
6
  module DRb
7
7
 
8
+ # The protocol for DRb over an SSL socket
9
+ #
10
+ # The URI for a DRb socket over SSL is:
11
+ # <code>drbssl://<host>:<port>?<option></code>. The option is optional
8
12
  class DRbSSLSocket < DRbTCPSocket
9
13
 
14
+ # SSLConfig handles the needed SSL information for establishing a
15
+ # DRbSSLSocket connection, including generating the X509 / RSA pair.
16
+ #
17
+ # An instance of this config can be passed to DRbSSLSocket.new,
18
+ # DRbSSLSocket.open and DRbSSLSocket.open_server
19
+ #
20
+ # See DRb::DRbSSLSocket::SSLConfig.new for more details
10
21
  class SSLConfig
11
22
 
23
+ # Default values for a SSLConfig instance.
24
+ #
25
+ # See DRb::DRbSSLSocket::SSLConfig.new for more details
12
26
  DEFAULT = {
13
- :SSLCertificate => nil,
14
- :SSLPrivateKey => nil,
15
- :SSLClientCA => nil,
16
- :SSLCACertificatePath => nil,
17
- :SSLCACertificateFile => nil,
18
- :SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
19
- :SSLVerifyDepth => nil,
20
- :SSLVerifyCallback => nil, # custom verification
27
+ :SSLCertificate => nil,
28
+ :SSLPrivateKey => nil,
29
+ :SSLClientCA => nil,
30
+ :SSLCACertificatePath => nil,
31
+ :SSLCACertificateFile => nil,
32
+ :SSLTmpDhCallback => nil,
33
+ :SSLVerifyMode => ::OpenSSL::SSL::VERIFY_NONE,
34
+ :SSLVerifyDepth => nil,
35
+ :SSLVerifyCallback => nil, # custom verification
21
36
  :SSLCertificateStore => nil,
22
- # Must specify if you use auto generated certificate.
23
- :SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
24
- :SSLCertComment => "Generated by Ruby/OpenSSL"
37
+ # Must specify if you use auto generated certificate.
38
+ :SSLCertName => nil, # e.g. [["CN","fqdn.example.com"]]
39
+ :SSLCertComment => "Generated by Ruby/OpenSSL"
25
40
  }
26
41
 
42
+ # Create a new DRb::DRbSSLSocket::SSLConfig instance
43
+ #
44
+ # The DRb::DRbSSLSocket will take either a +config+ Hash or an instance
45
+ # of SSLConfg, and will setup the certificate for its session for the
46
+ # configuration. If want it to generate a generic certificate, the bare
47
+ # minimum is to provide the :SSLCertName
48
+ #
49
+ # === Config options
50
+ #
51
+ # From +config+ Hash:
52
+ #
53
+ # :SSLCertificate ::
54
+ # An instance of OpenSSL::X509::Certificate. If this is not provided,
55
+ # then a generic X509 is generated, with a correspond :SSLPrivateKey
56
+ #
57
+ # :SSLPrivateKey ::
58
+ # A private key instance, like OpenSSL::PKey::RSA. This key must be
59
+ # the key that signed the :SSLCertificate
60
+ #
61
+ # :SSLClientCA ::
62
+ # An OpenSSL::X509::Certificate, or Array of certificates that will
63
+ # used as ClientCAs in the SSL Context
64
+ #
65
+ # :SSLCACertificatePath ::
66
+ # A path to the directory of CA certificates. The certificates must
67
+ # be in PEM format.
68
+ #
69
+ # :SSLCACertificateFile ::
70
+ # A path to a CA certificate file, in PEM format.
71
+ #
72
+ # :SSLTmpDhCallback ::
73
+ # A DH callback. See OpenSSL::SSL::SSLContext.tmp_dh_callback
74
+ #
75
+ # :SSLVerifyMode ::
76
+ # This is the SSL verification mode. See OpenSSL::SSL::VERIFY_* for
77
+ # available modes. The default is OpenSSL::SSL::VERIFY_NONE
78
+ #
79
+ # :SSLVerifyDepth ::
80
+ # Number of CA certificates to walk, when verifying a certificate
81
+ # chain.
82
+ #
83
+ # :SSLVerifyCallback ::
84
+ # A callback to be used for additional verification. See
85
+ # OpenSSL::SSL::SSLContext.verify_callback
86
+ #
87
+ # :SSLCertificateStore ::
88
+ # A OpenSSL::X509::Store used for verification of certificates
89
+ #
90
+ # :SSLCertName ::
91
+ # Issuer name for the certificate. This is required when generating
92
+ # the certificate (if :SSLCertificate and :SSLPrivateKey were not
93
+ # given). The value of this is to be an Array of pairs:
94
+ #
95
+ # [["C", "Raleigh"], ["ST","North Carolina"],
96
+ # ["CN","fqdn.example.com"]]
97
+ #
98
+ # See also OpenSSL::X509::Name
99
+ #
100
+ # :SSLCertComment ::
101
+ # A comment to be used for generating the certificate. The default is
102
+ # "Generated by Ruby/OpenSSL"
103
+ #
104
+ #
105
+ # === Example
106
+ #
107
+ # These values can be added after the fact, like a Hash.
108
+ #
109
+ # require 'drb/ssl'
110
+ # c = DRb::DRbSSLSocket::SSLConfig.new {}
111
+ # c[:SSLCertificate] =
112
+ # OpenSSL::X509::Certificate.new(File.read('mycert.crt'))
113
+ # c[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.read('mycert.key'))
114
+ # c[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
115
+ # c[:SSLCACertificatePath] = "/etc/ssl/certs/"
116
+ # c.setup_certificate
117
+ #
118
+ # or
119
+ #
120
+ # require 'drb/ssl'
121
+ # c = DRb::DRbSSLSocket::SSLConfig.new({
122
+ # :SSLCertName => [["CN" => DRb::DRbSSLSocket.getservername]]
123
+ # })
124
+ # c.setup_certificate
125
+ #
27
126
  def initialize(config)
28
- @config = config
127
+ @config = config
29
128
  @cert = config[:SSLCertificate]
30
129
  @pkey = config[:SSLPrivateKey]
31
130
  @ssl_ctx = nil
32
131
  end
33
132
 
34
- def [](key);
35
- @config[key] || DEFAULT[key]
133
+ # A convenience method to access the values like a Hash
134
+ def [](key);
135
+ @config[key] || DEFAULT[key]
36
136
  end
37
137
 
138
+ # Connect to IO +tcp+, with context of the current certificate
139
+ # configuration
38
140
  def connect(tcp)
39
- ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
40
- ssl.sync = true
41
- ssl.connect
42
- ssl
141
+ ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
142
+ ssl.sync = true
143
+ ssl.connect
144
+ ssl
43
145
  end
44
-
146
+
147
+ # Accept connection to IO +tcp+, with context of the current certificate
148
+ # configuration
45
149
  def accept(tcp)
46
- ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
47
- ssl.sync = true
48
- ssl.accept
49
- ssl
150
+ ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
151
+ ssl.sync = true
152
+ ssl.accept
153
+ ssl
50
154
  end
51
-
155
+
156
+ # Ensures that :SSLCertificate and :SSLPrivateKey have been provided
157
+ # or that a new certificate is generated with the other parameters
158
+ # provided.
52
159
  def setup_certificate
53
160
  if @cert && @pkey
54
161
  return
55
162
  end
56
163
 
57
- rsa = OpenSSL::PKey::RSA.new(512){|p, n|
58
- next unless self[:verbose]
59
- case p
60
- when 0; $stderr.putc "." # BN_generate_prime
61
- when 1; $stderr.putc "+" # BN_generate_prime
62
- when 2; $stderr.putc "*" # searching good prime,
63
- # n = #of try,
64
- # but also data from BN_generate_prime
65
- when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
66
- # but also data from BN_generate_prime
67
- else; $stderr.putc "*" # BN_generate_prime
68
- end
69
- }
70
-
71
- cert = OpenSSL::X509::Certificate.new
72
- cert.version = 3
73
- cert.serial = 0
74
- name = OpenSSL::X509::Name.new(self[:SSLCertName])
75
- cert.subject = name
76
- cert.issuer = name
77
- cert.not_before = Time.now
78
- cert.not_after = Time.now + (365*24*60*60)
79
- cert.public_key = rsa.public_key
80
-
81
- ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
82
- cert.extensions = [
83
- ef.create_extension("basicConstraints","CA:FALSE"),
84
- ef.create_extension("subjectKeyIdentifier", "hash") ]
85
- ef.issuer_certificate = cert
86
- cert.add_extension(ef.create_extension("authorityKeyIdentifier",
87
- "keyid:always,issuer:always"))
88
- if comment = self[:SSLCertComment]
89
- cert.add_extension(ef.create_extension("nsComment", comment))
90
- end
91
- cert.sign(rsa, OpenSSL::Digest::SHA1.new)
92
-
93
- @cert = cert
164
+ rsa = OpenSSL::PKey::RSA.new(1024){|p, n|
165
+ next unless self[:verbose]
166
+ case p
167
+ when 0; $stderr.putc "." # BN_generate_prime
168
+ when 1; $stderr.putc "+" # BN_generate_prime
169
+ when 2; $stderr.putc "*" # searching good prime,
170
+ # n = #of try,
171
+ # but also data from BN_generate_prime
172
+ when 3; $stderr.putc "\n" # found good prime, n==0 - p, n==1 - q,
173
+ # but also data from BN_generate_prime
174
+ else; $stderr.putc "*" # BN_generate_prime
175
+ end
176
+ }
177
+
178
+ cert = OpenSSL::X509::Certificate.new
179
+ cert.version = 3
180
+ cert.serial = 0
181
+ name = OpenSSL::X509::Name.new(self[:SSLCertName])
182
+ cert.subject = name
183
+ cert.issuer = name
184
+ cert.not_before = Time.now
185
+ cert.not_after = Time.now + (365*24*60*60)
186
+ cert.public_key = rsa.public_key
187
+
188
+ ef = OpenSSL::X509::ExtensionFactory.new(nil,cert)
189
+ cert.extensions = [
190
+ ef.create_extension("basicConstraints","CA:FALSE"),
191
+ ef.create_extension("subjectKeyIdentifier", "hash") ]
192
+ ef.issuer_certificate = cert
193
+ cert.add_extension(ef.create_extension("authorityKeyIdentifier",
194
+ "keyid:always,issuer:always"))
195
+ if comment = self[:SSLCertComment]
196
+ cert.add_extension(ef.create_extension("nsComment", comment))
197
+ end
198
+ cert.sign(rsa, OpenSSL::Digest::SHA1.new)
199
+
200
+ @cert = cert
94
201
  @pkey = rsa
95
202
  end
96
203
 
204
+ # Establish the OpenSSL::SSL::SSLContext with the configuration
205
+ # parameters provided.
97
206
  def setup_ssl_context
98
207
  ctx = ::OpenSSL::SSL::SSLContext.new
99
208
  ctx.cert = @cert
100
209
  ctx.key = @pkey
101
- ctx.client_ca = self[:SSLClientCA]
102
- ctx.ca_path = self[:SSLCACertificatePath]
103
- ctx.ca_file = self[:SSLCACertificateFile]
104
- ctx.verify_mode = self[:SSLVerifyMode]
105
- ctx.verify_depth = self[:SSLVerifyDepth]
106
- ctx.verify_callback = self[:SSLVerifyCallback]
210
+ ctx.client_ca = self[:SSLClientCA]
211
+ ctx.ca_path = self[:SSLCACertificatePath]
212
+ ctx.ca_file = self[:SSLCACertificateFile]
213
+ ctx.tmp_dh_callback = self[:SSLTmpDhCallback]
214
+ ctx.verify_mode = self[:SSLVerifyMode]
215
+ ctx.verify_depth = self[:SSLVerifyDepth]
216
+ ctx.verify_callback = self[:SSLVerifyCallback]
107
217
  ctx.cert_store = self[:SSLCertificateStore]
108
218
  @ssl_ctx = ctx
109
219
  end
110
220
  end
111
221
 
112
- def self.parse_uri(uri)
222
+ # Parse the dRuby +uri+ for an SSL connection.
223
+ #
224
+ # Expects drbssl://...
225
+ #
226
+ # Raises DRbBadScheme or DRbBadURI if +uri+ is not matching or malformed
227
+ def self.parse_uri(uri) # :nodoc:
113
228
  if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
114
- host = $1
115
- port = $2.to_i
116
- option = $4
117
- [host, port, option]
229
+ host = $1
230
+ port = $2.to_i
231
+ option = $4
232
+ [host, port, option]
118
233
  else
119
- raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
120
- raise(DRbBadURI, 'can\'t parse uri:' + uri)
234
+ raise(DRbBadScheme, uri) unless uri =~ /^drbssl:/
235
+ raise(DRbBadURI, 'can\'t parse uri:' + uri)
121
236
  end
122
237
  end
123
238
 
239
+ # Return an DRb::DRbSSLSocket instance as a client-side connection,
240
+ # with the SSL connected. This is called from DRb::start_service or while
241
+ # connecting to a remote object:
242
+ #
243
+ # DRb.start_service 'drbssl://localhost:0', front, config
244
+ #
245
+ # +uri+ is the URI we are connected to,
246
+ # <code>'drbssl://localhost:0'</code> above, +config+ is our
247
+ # configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
124
248
  def self.open(uri, config)
125
- host, port, option = parse_uri(uri)
249
+ host, port, = parse_uri(uri)
126
250
  host.untaint
127
251
  port.untaint
128
252
  soc = TCPSocket.open(host, port)
@@ -132,59 +256,88 @@ module DRb
132
256
  self.new(uri, ssl, ssl_conf, true)
133
257
  end
134
258
 
259
+ # Returns a DRb::DRbSSLSocket instance as a server-side connection, with
260
+ # the SSL connected. This is called from DRb::start_service or while
261
+ # connecting to a remote object:
262
+ #
263
+ # DRb.start_service 'drbssl://localhost:0', front, config
264
+ #
265
+ # +uri+ is the URI we are connected to,
266
+ # <code>'drbssl://localhost:0'</code> above, +config+ is our
267
+ # configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
135
268
  def self.open_server(uri, config)
136
269
  uri = 'drbssl://:0' unless uri
137
- host, port, opt = parse_uri(uri)
270
+ host, port, = parse_uri(uri)
138
271
  if host.size == 0
139
272
  host = getservername
140
273
  soc = open_server_inaddr_any(host, port)
141
274
  else
142
- soc = TCPServer.open(host, port)
275
+ soc = TCPServer.open(host, port)
143
276
  end
144
277
  port = soc.addr[1] if port == 0
145
278
  @uri = "drbssl://#{host}:#{port}"
146
-
279
+
147
280
  ssl_conf = SSLConfig.new(config)
148
281
  ssl_conf.setup_certificate
149
282
  ssl_conf.setup_ssl_context
150
283
  self.new(@uri, soc, ssl_conf, false)
151
284
  end
152
285
 
153
- def self.uri_option(uri, config)
286
+ # This is a convenience method to parse +uri+ and separate out any
287
+ # additional options appended in the +uri+.
288
+ #
289
+ # Returns an option-less uri and the option => [uri,option]
290
+ #
291
+ # The +config+ is completely unused, so passing nil is sufficient.
292
+ def self.uri_option(uri, config) # :nodoc:
154
293
  host, port, option = parse_uri(uri)
155
294
  return "drbssl://#{host}:#{port}", option
156
295
  end
157
296
 
297
+ # Create a DRb::DRbSSLSocket instance.
298
+ #
299
+ # +uri+ is the URI we are connected to.
300
+ # +soc+ is the tcp socket we are bound to.
301
+ # +config+ is our configuration. Either a Hash or SSLConfig
302
+ # +is_established+ is a boolean of whether +soc+ is currenly established
303
+ #
304
+ # This is called automatically based on the DRb protocol.
158
305
  def initialize(uri, soc, config, is_established)
159
306
  @ssl = is_established ? soc : nil
160
307
  super(uri, soc.to_io, config)
161
308
  end
162
-
163
- def stream; @ssl; end
164
309
 
165
- def close
310
+ # Returns the SSL stream
311
+ def stream; @ssl; end # :nodoc:
312
+
313
+ # Closes the SSL stream before closing the dRuby connection.
314
+ def close # :nodoc:
166
315
  if @ssl
167
- @ssl.close
168
- @ssl = nil
316
+ @ssl.close
317
+ @ssl = nil
169
318
  end
170
319
  super
171
320
  end
172
-
173
- def accept
321
+
322
+ def accept # :nodoc:
174
323
  begin
175
324
  while true
176
- soc = @socket.accept
177
- break if (@acl ? @acl.allow_socket?(soc) : true)
178
- soc.close
325
+ soc = @socket.accept
326
+ break if (@acl ? @acl.allow_socket?(soc) : true)
327
+ soc.close
328
+ end
329
+ begin
330
+ ssl = @config.accept(soc)
331
+ ensure
332
+ soc.close if $!
179
333
  end
180
- ssl = @config.accept(soc)
181
334
  self.class.new(uri, ssl, @config, true)
182
335
  rescue OpenSSL::SSL::SSLError
183
- warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
184
- retry
336
+ warn("#{__FILE__}:#{__LINE__}: warning: #{$!.message} (#{$!.class})") if @config[:verbose]
337
+ retry
185
338
  end
186
339
  end
187
340
  end
188
-
341
+
189
342
  DRbProtocol.add_protocol(DRbSSLSocket)
190
343
  end