class DRbService
A base class for DRb-based services. Concrete subclasses must define the service API by declaring public methods. By default, any public methods are hidden until the client authenticates. You can optionally declare a subset of its API that is # accessible before authentication by wrapping them in an ‘unguarded’ block. # See DRbService::unguarded
for more details.
Constants
- DEFAULT_CERTNAME
The default path to the service cert, relative to the current directory
- DEFAULT_CONFIG
The default values for the drbservice config hash
- DEFAULT_IP
The default IP address to listen on
- DEFAULT_KEYNAME
The default path to the service key, relative to the current directory
- DEFAULT_PORT
The default port to listen on
- REVISION
Version-control revision
- VERSION
Library version
Attributes
The unguarded mode flag – instance methods defined while this flag is set will not be hidden
Public Class Methods
Inheritance callback: Add a per-class ‘unguarded mode’ flag to subclasses.
# File lib/drbservice.rb, line 105 def self::inherited( subclass ) self.log.debug "Setting @unguarded_mode in %p" % [ subclass ] subclass.instance_variable_set( :@unguarded_mode, false ) super end
Method-addition callback: Obscure the method meth
unless unguarded mode is enabled.
# File lib/drbservice.rb, line 86 def self::method_added( meth ) super unless self == ::DRbService || meth.to_sym == :initialize if !self.public_instance_methods.collect( &:to_sym ).include?( meth ) DRbService.log.debug "Not obsuring %p#%s: not a public method" % [ self, meth ] elsif self.unguarded_mode DRbService.log.debug "Not obscuring %p#%s: unguarded mode." % [ self, meth ] else DRbService.log.debug "Obscuring %p#%s." % [ self, meth ] @real_methods ||= {} @real_methods[ meth.to_sym ] = self.instance_method( meth ) remove_method( meth ) end end end
Create a new instance of the service. Raises a ScriptError if DRbService
is instantiated directly.
# File lib/drbservice.rb, line 146 def initialize( config={} ) raise ScriptError, "can't instantiate #{self.class} directly: please subclass it instead" if self.class == DRbService @authenticated = false end
Start the DRbService
, using the ip, port, and cert information from the given config
hash.
- :ip
-
the ip to bind to
- :port
-
the port to listen on
- :certfile
-
the name of the server’s SSL certificate file
- :keyfile
-
the name of the server’s SSL key file
# File lib/drbservice.rb, line 61 def self::start( config={} ) config = DEFAULT_CONFIG.merge( config ) frontobj = self.new( config ) uri = "drbssl://%s:%d" % config.values_at( :ip, :port ) cert = OpenSSL::X509::Certificate.new( File.read(config[:certfile]) ) key = OpenSSL::PKey::RSA.new( File.read(config[:keyfile]) ) config = { :safe_level => 1, :verbose => true, :SSLCertificate => cert, :SSLPrivateKey => key, } DRbService.log.info "Starting %p as a DRbService at %s" % [ self, uri ] server = DRb::DRbServer.new( uri, frontobj, config ) DRbService.log.debug " started. Joining the DRb thread." $0 = "%s %s" % [ self.name, uri ] server.thread.join end
Declare some service methods that can be called without authentication in the provided block.
# File lib/drbservice.rb, line 114 def self::unguarded self.unguarded_mode = true yield ensure self.unguarded_mode = false end
Return the library’s version string
# File lib/drbservice.rb, line 123 def self::version_string( include_buildnum=false ) vstring = "%s %s" % [ self.name, VERSION ] vstring << " (build %s)" % [ REVISION[/.*: ([[:xdigit:]]+)/, 1] || '0' ] if include_buildnum return vstring end
Public Instance Methods
Default authentication implementation – always fails. You’ll need to include one of the authentication modules or provide your own authenticate
method in your subclass.
# File lib/drbservice.rb, line 182 def authenticate( *args ) self.log.error "authentication failure (fallback method)" raise SecurityError, "authentication failure" end
Returns true
if the client has successfully authenticated.
# File lib/drbservice.rb, line 165 def authenticated? return @authenticated ? true : false end
Return a human-readable representation of the object.
# File lib/drbservice.rb, line 159 def inspect return "#<%s:0x%0x>" % [ self.class, self.__id__ * 2 ] end
Protected Instance Methods
Handle calls to guarded methods by requiring the authentication flag be set if there is a password set.
# File lib/drbservice.rb, line 194 def method_missing( sym, *args ) return super unless body = self.class.real_methods[ sym ] if self.authorized? return body.clone.bind( self ).call( *args ) else self.log.error "Guarded method %p called without authentication!" % [ sym ] raise SecurityError, "not authenticated" end end