XMLRPC::CGIServer nuby

Hi all,

I'm familiar with how to setup a standalone XMLRPC server, but I'm
curious about XMLRPC::CGIServer. Is this something that allows you to
slap rpc call results back to a webpage or something? I wasn't clear
from the examples in the documentation. I mean, how do you use this
thing?

I'm a CGI/web noob, in case you couldn't tell. I normally don't deal
with it, but I feel compelled to demonstrate to my coworkers that the
ridiculously bloated J2EE web service I'm working on can be reduced
significantly with Ruby. However, I need a little web interface for
"visual evidence" as it were.

If I'm off base, is there any sort of automated way to create an
XMLRPC server that will autogenerate a simple web page with links to
each handler? Then, each of those links would be a simple form where
I can pass values to the service and get results back in a web page?
Sorta like WebLogic does?

Am I making sense?

Help appreciated. Thanks.

Dan

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.

There are other ways to configure it, for example, as pure ruby application using XMLRPC::Server or XMLRPC::WEBrickServlet, or as a mod_ruby application XMLRPC::ModRubyServer.

Cheers,
Kent.

ยทยทยท

On Jul 2, 2004, at 2:27 AM, Daniel Berger wrote:

Hi all,

I'm familiar with how to setup a standalone XMLRPC server, but I'm
curious about XMLRPC::CGIServer. Is this something that allows you to
slap rpc call results back to a webpage or something? I wasn't clear
from the examples in the documentation. I mean, how do you use this
thing?

I'm a CGI/web noob, in case you couldn't tell. I normally don't deal
with it, but I feel compelled to demonstrate to my coworkers that the
ridiculously bloated J2EE web service I'm working on can be reduced
significantly with Ruby. However, I need a little web interface for
"visual evidence" as it were.

If I'm off base, is there any sort of automated way to create an
XMLRPC server that will autogenerate a simple web page with links to
each handler? Then, each of those links would be a simple form where
I can pass values to the service and get results back in a web page?
Sorta like WebLogic does?

Am I making sense?

Help appreciated. Thanks.

Dan

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