From: James Britt Date: 2004-07-03T01:25:22+09:00 Subject: Re: XMLRPC::CGIServer nuby Kent Sibilev wrote: > I think that XMLRPC:CGIServer is just another way to setup your XMLRPC > Server. Meaning that your XMLRPC requests will go through some CGI > capable web server like Apache, which invokes your XMLRPC:CGIServer. > This is some untested code assembled from some other code I've used in Blogtari. When given an xml-rpc request "someName.someMethod", along with its arguments, it tries to dynamically load the class SomeName (assumed to be in a file called SomeName.rb someplace in the 'require' path) and then invokes someMethod. So, to implement fooBar.add, with 2 args, you need to provide a class FooBar with a method add( x, y), and put it in a file called FooBar.rb (There's also a bit of code that checks to see if tis is running under mod_ruby.) One neat trick you can do with this arrangement is write an XML-RPC method that takes a code string and file name as arguments, and have it write out a new ruby file on the server. Then you can add new, or modify existing, XML-RPC functions using XML-RPC. Some security checks might be a good idea, though. #!/usr/local/bin/ruby # File index.rb require "xmlrpc/server" # You may also want to munge $: to ensure it # can find your request handler files. s = XMLRPC::CGIServer.new if defined? Apache s = XMLRPC::ModRubyServer.new end def new_from_name( classname, *args) cname = String.new( classname.untaint ) obj = nil begin obj = Object.const_get( cname ).new( *args ) rescue Exception begin require cname obj = Object.const_get( cname ).new( *args ) rescue Exception raise "Cannot create object #{cname}: #{$!}" unless obj end end obj end def call_dynamic( name, *args ) cname, mname = name.split( '.') begin handler = new_from_name( class_name_it( cname ) ) return handler.send( mname, *args) rescue raise "#{cname}::#{mname} is not implemented: #{$!}" end end s.set_default_handler do |name, *args| begin call_dynamic( name, *args ) rescue Exception raise XMLRPC::FaultException.new(-99, "#{$!}") end end s.serve