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