Project

General

Profile

Bug #7714 ยป ruby-doc_drb-20130118.patch

Much updated version of the previous patch. - vbatts (Vincent Batts), 01/20/2013 01:19 AM

View differences:

lib/drb/drb.rb
426 426

  
427 427
  # An exception wrapping an error object
428 428
  class DRbRemoteError < DRbError
429
    # Create a new DRb::DRbRemoteError
429 430
    def initialize(error)
430 431
      @reason = error.class.to_s
431 432
      super("#{error.message} (#{error.class})")
......
505 506
    end
506 507
  end
507 508

  
509
  # Class to wrap an Array.
510
  #
511
  # === Description
512
  #
513
  # A DRbArray can be provided in a DRb call. When the marshalled value
514
  # of a DRbArray object is unmarshalled, it returns the wrapped Array.
515
  #
516
  #
517
  # === Examples
518
  #
519
  #   a = %w{ cats and dogs }
520
  #   => ["cats", "and", "dogs"]
521
  #   da = DRb::DRbArray.new(a)
522
  #   => #<DRb::DRbArray:0x0000000068b0f0 @ary=["cats", "and", "dogs"]>
523
  #   bin = Marshal.dump(h)
524
  #   => "\x04\bu:\x12DRb::DRbArray*\x04\b[\bI\"\tcats\x06:\x06ETI\"\band\x06;\0TI\"\tdogs\x06;\0T"
525
  #   Marshal.load(bin)
526
  #   => ["cats", "and", "dogs"]
527
  #
508 528
  class DRbArray
529
    # Create a DRb::DRbArray object
530
    #
531
    # +ary+ is an Array
509 532
    def initialize(ary)
510 533
      @ary = ary.collect { |obj|
511 534
        if obj.kind_of? DRbUndumped
......
521 544
      }
522 545
    end
523 546

  
524
    def self._load(s)
547
    def self._load(s) # :nodoc:
525 548
      Marshal::load(s)
526 549
    end
527 550

  
528
    def _dump(lv)
551
    def _dump(lv) # :nodoc:
529 552
      Marshal.dump(@ary)
530 553
    end
531 554
  end
......
629 652
    end
630 653

  
631 654
    private
632
    def make_proxy(obj, error=false)
655
    def make_proxy(obj, error=false) # :nodoc:
633 656
      if error
634 657
        DRbRemoteError.new(obj)
635 658
      else
......
798 821
  # Communicates over a TCP socket.
799 822
  class DRbTCPSocket
800 823
    private
801
    def self.parse_uri(uri)
824
    def self.parse_uri(uri) # :nodoc:
802 825
      if uri =~ /^druby:\/\/(.*?):(\d+)(\?(.*))?$/
803 826
        host = $1
804 827
        port = $2.to_i
......
812 835

  
813 836
    public
814 837

  
815
    # Open a client connection to +uri+ using configuration +config+.
838
    # Open a client connection to +uri+ (String)
839
    # using configuration +config+.
840
    #
841
    # Can raise DRbBadScheme or DRbBadURI if +uri+
842
    # is not 'druby:...' or is malformed
843
    # See DRb::DRbServer.new for information on the uri.
816 844
    def self.open(uri, config)
817 845
      host, port, = parse_uri(uri)
818 846
      host.untaint
......
821 849
      self.new(uri, soc, config)
822 850
    end
823 851

  
852
    # Return the hostname (String) of this server
824 853
    def self.getservername
825 854
      host = Socket::gethostname
826 855
      begin
......
830 859
      end
831 860
    end
832 861

  
862
    # For the +host+ (String) provided
863
    # return a TCPServer on +port+ (Fixnum)
833 864
    def self.open_server_inaddr_any(host, port)
834 865
      infos = Socket::getaddrinfo(host, nil,
835 866
                                  Socket::AF_UNSPEC,
......
1008 1039
      self.new_with(uri, ref)
1009 1040
    end
1010 1041

  
1042
    # Create a DRb::DRbObject given the reference information to the
1043
    # remote host uri String, and ref
1011 1044
    def self.new_with(uri, ref)
1012 1045
      it = self.allocate
1013 1046
      it.instance_variable_set(:@uri, uri)
......
1094 1127
      end
1095 1128
    end
1096 1129

  
1130
    # Given the +uri+ String of another dRuby host,
1131
    # execute the &blok provided.
1132
    #
1133
    # Returns Array with [<boolean of success>, <result object>]
1097 1134
    def self.with_friend(uri)
1098 1135
      friend = DRb.fetch_server(uri)
1099 1136
      return yield() unless friend
......
1105 1142
      Thread.current['DRb'] = save if friend
1106 1143
    end
1107 1144

  
1145
    # Given +uri+ String and a +result+, that responds like an Exception,
1146
    # return an Array of the backtrace, relative the +uri+
1108 1147
    def self.prepare_backtrace(uri, result)
1109 1148
      prefix = "(#{uri}) "
1110 1149
      bt = []
......
1238 1277

  
1239 1278
    # Set the default value for the :acl option.
1240 1279
    #
1280
    # +acl+ is expected to be an ACL object.
1281
    #
1241 1282
    # See #new().  The initial default value is nil.
1242 1283
    def self.default_acl(acl)
1243 1284
      @@acl = acl
......
1250 1291
      @@idconv = idconv
1251 1292
    end
1252 1293

  
1294
    # Set the default value for the :safe_level option.
1295
    #
1296
    # See #new().  The initial default value is 0.
1253 1297
    def self.default_safe_level(level)
1254 1298
      @@safe_level = level
1255 1299
    end
......
1307 1351
    # :argc_limit :: the maximum number of arguments to a remote
1308 1352
    #                method accepted by the server.  Defaults to
1309 1353
    #                256.
1354
    # :safe_level :: The safety level of the DRbServer. The attribute
1355
    #                sets the $SAFE for methods performed in 
1356
    #                #main_loop.  Defaults to 0.
1310 1357
    #
1311 1358
    # The default values of these options can be modified on
1312 1359
    # a class-wide basis by the class methods #default_argc_limit,
......
1366 1413
    # The configuration of this DRbServer
1367 1414
    attr_reader :config
1368 1415

  
1416
    # The safety level of this DRbServer
1417
    #
1418
    # This is to be a Fixnum, corresponding with $SAFE
1419
    #
1420
    # Default +safe_level+ is 0
1369 1421
    attr_reader :safe_level
1370 1422

  
1371 1423
    # Set whether to operate in verbose mode.
......
1383 1435
      @thread.alive?
1384 1436
    end
1385 1437

  
1438
    # Check whether +uri+ (String) is in the set of known URIs
1386 1439
    def here?(uri)
1387 1440
      @exported_uri.include?(uri)
1388 1441
    end
......
1411 1464
    end
1412 1465

  
1413 1466
    private
1414
    def run
1467
    def run # :nodoc:
1415 1468
      Thread.start do
1416 1469
        begin
1417 1470
          while true
......
1722 1775

  
1723 1776
  # Set the default id conv object.
1724 1777
  #
1778
  # This expected to be an instance, like DRb::DRbIdConv,
1779
  # that responds to #to_id and #to_obj
1780
  #
1725 1781
  # See DRbServer#default_id_conv.
1726 1782
  def install_id_conv(idconv)
1727 1783
    DRbServer.default_id_conv(idconv)
1728 1784
  end
1729 1785
  module_function :install_id_conv
1730 1786

  
1731
  # Set the default acl.
1787
  # Set the default ACL +acl+.
1732 1788
  #
1733 1789
  # See DRb::DRbServer.default_acl.
1734 1790
  def install_acl(acl)
......
1737 1793
  module_function :install_acl
1738 1794

  
1739 1795
  @mutex = Mutex.new
1796
  # Get the semaphore for this DRb module
1797
  #
1798
  # Returns a Mutex instance
1740 1799
  def mutex
1741 1800
    @mutex
1742 1801
  end
1743 1802
  module_function :mutex
1744 1803

  
1745 1804
  @server = {}
1805
  # Recored the DRb::DRbServer +server+
1806
  #
1807
  # This is called when a new DRb::DRbServer instance is created.
1808
  #
1809
  #   require 'drb'
1810
  #
1811
  #   s = DRb::DRbServer.new
1812
  #   => #<DRb::DRbServer:0x00000001dcb440 @config={:idconv=>#<DRb::...
1813
  #   DRb.fetch_server(s.uri)
1814
  #   => #<DRb::DRbServer:0x00000001dcb440 @config={:idconv=>#<DRb::...
1815
  #
1746 1816
  def regist_server(server)
1747 1817
    @server[server.uri] = server
1748 1818
    mutex.synchronize do
......
1751 1821
  end
1752 1822
  module_function :regist_server
1753 1823

  
1824
  # Remove the DRb::DRbServer +server+ from the registered list
1754 1825
  def remove_server(server)
1755 1826
    @server.delete(server.uri)
1756 1827
  end
1757 1828
  module_function :remove_server
1758 1829

  
1830
  # Return the DRb::DRbServer object, provided the String +uri+.
1831
  #
1832
  # This is provided from the registered servers.
1833
  # See also #regist_server and #remove_server
1759 1834
  def fetch_server(uri)
1760 1835
    @server[uri]
1761 1836
  end
lib/drb/ssl.rb
5 5

  
6 6
module DRb
7 7

  
8
  # DRb::DRbSSLSocket handles making a dRuby connection over an SSL connection
8 9
  class DRbSSLSocket < DRbTCPSocket
9 10

  
11
    # SSLConfig handles the needed SSL information for establishing 
12
    # a DRbSSLSocket connection, including generating the X509 / RSA pair.
13
    #
14
    # An instance of this config can be passed to DRbSSLSocket.new,
15
    # DRbSSLSocket.open and DRbSSLSocket.open_server
16
    #
17
    # See DRb::DRbSSLSocket::SSLConfig.new for more details
10 18
    class SSLConfig
11 19

  
20
      # Default values for a SSLConfig instance.
21
      # 
22
      # See DRb::DRbSSLSocket::SSLConfig.new for more details
12 23
      DEFAULT = {
13 24
        :SSLCertificate       => nil,
14 25
        :SSLPrivateKey        => nil,
......
25 36
        :SSLCertComment       => "Generated by Ruby/OpenSSL"
26 37
      }
27 38

  
39
      # Create a new DRb::DRbSSLSocket::SSLConfig instance
40
      #
41
      # The DRb::DRbSSLSocket will take either a +config+ Hash or an instance
42
      # of SSLConfg, and will setup the certificate for its session for the 
43
      # configuration. If want it to generate a generic certificate, the bare
44
      # minimum is to provide the :SSLCertName 
45
      #
46
      # === Config options
47
      # From +config+ Hash
48
      #
49
      # :SSLCertificate :: An instance of OpenSSL::X509::Certificate.
50
      #                    If this is not provided, then a generic X509 is 
51
      #                    generated, with a correspond :SSLPrivateKey
52
      # :SSLPrivateKey :: A private key instance, like OpenSSL::PKey::RSA.
53
      #                   This key must be the key that signed the
54
      #                   :SSLCertificate
55
      # :SSLClientCA :: An OpenSSL::X509::Certificate, or Array of certificates
56
      #                 that will used as ClientCAs in the SSL Context
57
      # :SSLCACertificatePath :: A path to the directory of CA certificates.
58
      #                          The certificates are to be in PEM format.
59
      # :SSLCACertificateFile :: A path to a CA certificate file, in PEM format.
60
      # :SSLTmpDhCallback :: A DH callback. See
61
      #                      OpenSSL::SSL::SSLContext.tmp_dh_callback
62
      # :SSLVerifyMode :: This is the SSL verification mode.
63
      #                   See OpenSSL::SSL::VERIFY_* for available modes.
64
      #                   Default is OpenSSL::SSL::VERIFY_NONE
65
      # :SSLVerifyDepth :: Number of CA certificates to walk, when verify a 
66
      #                    certificate chain.
67
      # :SSLVerifyCallback :: A callback to be used for additional verification.
68
      #                       See OpenSSL::SSL::SSLContext.verify_callback
69
      # :SSLCertificateStore :: A OpenSSL::X509::Store used for verification
70
      #                         of certificates
71
      # :SSLCertName :: Issuer name for the certificate.
72
      #                 This is required when generating the certificate
73
      #                 (if :SSLCertificate and :SSLPrivateKey were not given)
74
      #                 The value of this is to be an Array of pairs. i.e.
75
      #                 [["C", "Raleigh"], ["ST","North Carolina"], ["CN","fqdn.example.com"]]
76
      # :SSLCertComment :: A comment to be used for generating the certificate.
77
      #                    Default is "Generated by Ruby/OpenSSL"
78
      #
79
      #
80
      # === Example
81
      # These values can be added after the fact, like a Hash.
82
      # 
83
      #   require 'drb/ssl'
84
      #   c = DRb::DRbSSLSocket::SSLConfig.new {}
85
      #   c[:SSLCertificate] = OpenSSL::X509::Certificate.new(File.read('mycert.crt'))
86
      #   c[:SSLPrivateKey] = OpenSSL::PKey::RSA.new(File.read('mycert.key'))
87
      #   c[:SSLVerifyMode] = OpenSSL::SSL::VERIFY_PEER
88
      #   c[:SSLCACertificatePath] = "/etc/ssl/certs/"
89
      #   c.setup_certificate
90
      #
91
      # or
92
      #
93
      #   require 'drb/ssl'
94
      #   c = DRb::DRbSSLSocket::SSLConfig.new({
95
      #           :SSLCertName => [["CN" => DRb::DRbSSLSocket.getservername]]
96
      #           })
97
      #   c.setup_certificate
98
      #
28 99
      def initialize(config)
29 100
        @config  = config
30 101
        @cert    = config[:SSLCertificate]
......
32 103
        @ssl_ctx = nil
33 104
      end
34 105

  
106
      # A convenience method to access the values like a Hash
35 107
      def [](key);
36 108
        @config[key] || DEFAULT[key]
37 109
      end
38 110

  
111
      # Connect to IO +tcp+,
112
      # with context of the current certificate configuration
39 113
      def connect(tcp)
40 114
        ssl = ::OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
41 115
        ssl.sync = true
......
43 117
        ssl
44 118
      end
45 119

  
120
      # Accept connection to IO +tcp+,
121
      # with context of the current certificate configuration
46 122
      def accept(tcp)
47 123
        ssl = OpenSSL::SSL::SSLSocket.new(tcp, @ssl_ctx)
48 124
        ssl.sync = true
......
50 126
        ssl
51 127
      end
52 128

  
129
      # Ensures that :SSLCertificate and :SSLPrivateKey have been provided
130
      # or that a new certificate is generated with the other parameters
131
      # provided.
53 132
      def setup_certificate
54 133
        if @cert && @pkey
55 134
          return
......
95 174
        @pkey = rsa
96 175
      end
97 176

  
177
      # Establish the OpenSSL::SSL::SSLContext with the configuration
178
      # parameters provided.
98 179
      def setup_ssl_context
99 180
        ctx = ::OpenSSL::SSL::SSLContext.new
100 181
        ctx.cert            = @cert
......
111 192
      end
112 193
    end
113 194

  
195
    # Parse the dRuby +uri+ for an SSL connection.
196
    #
197
    # Expects drbssl://...
198
    #
199
    # Raises DRbBadScheme or DRbBadURI if +uri+ is not matching or malformed
114 200
    def self.parse_uri(uri)
115 201
      if uri =~ /^drbssl:\/\/(.*?):(\d+)(\?(.*))?$/
116 202
        host = $1
......
123 209
      end
124 210
    end
125 211

  
212
    # Return an DRb::DRbSSLSocket instance as a client-side connection,
213
    # with the SSL connected.
214
    #
215
    # +uri+ is the URI we are connected to.
216
    # +config+ is our configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
217
    #  
126 218
    def self.open(uri, config)
127 219
      host, port, = parse_uri(uri)
128 220
      host.untaint
......
134 226
      self.new(uri, ssl, ssl_conf, true)
135 227
    end
136 228

  
229
    # Return an DRb::DRbSSLSocket instance as a server-side connection,
230
    # with the SSL connected.
231
    #
232
    # +uri+ is the URI we are connected to.
233
    # +config+ is our configuration. Either a Hash or DRb::DRbSSLSocket::SSLConfig
234
    #  
137 235
    def self.open_server(uri, config)
138 236
      uri = 'drbssl://:0' unless uri
139 237
      host, port, = parse_uri(uri)
......
152 250
      self.new(@uri, soc, ssl_conf, false)
153 251
    end
154 252

  
253
    # This is a convenience method to parse +uri+ and separate out any
254
    # additional options appended in the +uri+.
255
    #
256
    # Returns an option-less uri and the option => [uri,option]
257
    #
258
    # The +config+ is completely unused, so passing nil is sufficient.
155 259
    def self.uri_option(uri, config)
156 260
      host, port, option = parse_uri(uri)
157 261
      return "drbssl://#{host}:#{port}", option
158 262
    end
159 263

  
264
    # Create a DRb::DRbSSLSocket instance. 
265
    #
266
    # +uri+ is the URI we are connected to.
267
    # +soc+ is the tcp socket we are bound to.
268
    # +config+ is our configuration. Either a Hash or SSLConfig
269
    # +is_established+ is a boolean of whether +soc+ is currenly established
160 270
    def initialize(uri, soc, config, is_established)
161 271
      @ssl = is_established ? soc : nil
162 272
      super(uri, soc.to_io, config)
163 273
    end
164 274

  
275
    # Returns the SSL stream
165 276
    def stream; @ssl; end
166 277

  
278
    # Closes the SSL stream before closing the dRuby connection.
167 279
    def close
168 280
      if @ssl
169 281
        @ssl.close