rubysl-drb 1.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -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