summaryrefslogtreecommitdiff
path: root/trunk/lib/xmlrpc/README.rdoc
diff options
context:
space:
mode:
authoryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-25 15:02:05 +0000
committeryugui <yugui@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>2008-08-25 15:02:05 +0000
commit0dc342de848a642ecce8db697b8fecd83a63e117 (patch)
tree2b7ed4724aff1f86073e4740134bda9c4aac1a39 /trunk/lib/xmlrpc/README.rdoc
parentef70cf7138ab8034b5b806f466e4b484b24f0f88 (diff)
added tag v1_9_0_4
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_9_0_4@18845 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'trunk/lib/xmlrpc/README.rdoc')
-rw-r--r--trunk/lib/xmlrpc/README.rdoc300
1 files changed, 300 insertions, 0 deletions
diff --git a/trunk/lib/xmlrpc/README.rdoc b/trunk/lib/xmlrpc/README.rdoc
new file mode 100644
index 0000000000..221d675219
--- /dev/null
+++ b/trunk/lib/xmlrpc/README.rdoc
@@ -0,0 +1,300 @@
+= XMLRPC for Ruby
+
+== Author and Copyright
+
+Copyright (C) 2001-2004 by Michael Neumann (mailto:mneumann@ntecs.de)
+
+Released under the same term of license as Ruby.
+
+== Overview
+
+XMLRPC is a lightweight protocol that enables remote procedure calls over
+HTTP. It is defined at http://www.xmlrpc.com.
+
+XMLRPC allows you to create simple distributed computing solutions that span
+computer languages. Its distinctive feature is its simplicity compared to
+other approaches like SOAP and CORBA.
+
+The Ruby standard library package 'xmlrpc' enables you to create a server that
+implements remote procedures and a client that calls them. Very little code
+is required to achieve either of these.
+
+== Example
+
+Try the following code. It calls a standard demonstration remote procedure.
+
+ require 'xmlrpc/client'
+ require 'pp'
+
+ server = XMLRPC::Client.new2("http://xmlrpc-c.sourceforge.net/api/sample.php")
+ result = server.call("sample.sumAndDifference", 5, 3)
+ pp result
+
+== Documentation
+
+See http://www.ntecs.de/projects/xmlrpc4r. There is plenty of detail there to
+use the client and implement a server.
+
+== Features of XMLRPC for Ruby
+
+* Extensions
+ * Introspection
+ * multiCall
+ * optionally nil values and integers larger than 32 Bit
+
+* Server
+ * Standalone XML-RPC server
+ * CGI-based (works with FastCGI)
+ * Apache mod_ruby server
+ * WEBrick servlet
+
+* Client
+ * synchronous/asynchronous calls
+ * Basic HTTP-401 Authentification
+ * HTTPS protocol (SSL)
+
+* Parsers
+ * NQXML (NQXMLStreamParser, NQXMLTreeParser)
+ * Expat (XMLStreamParser, XMLTreeParser)
+ * REXML (REXMLStreamParser)
+ * xml-scan (XMLScanStreamParser)
+ * Fastest parser is Expat's XMLStreamParser!
+
+* General
+ * possible to choose between XMLParser module (Expat wrapper) and REXML/NQXML (pure Ruby) parsers
+ * Marshalling Ruby objects to Hashs and reconstruct them later from a Hash
+ * SandStorm component architecture Client interface
+
+== Howto
+
+=== Client
+
+ require "xmlrpc/client"
+
+ # Make an object to represent the XML-RPC server.
+ server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
+
+ # Call the remote server and get our result
+ result = server.call("sample.sumAndDifference", 5, 3)
+
+ sum = result["sum"]
+ difference = result["difference"]
+
+ puts "Sum: #{sum}, Difference: #{difference}"
+
+=== Client with XML-RPC fault-structure handling
+
+There are two possible ways, of handling a fault-structure:
+
+==== by catching a XMLRPC::FaultException exception
+
+ require "xmlrpc/client"
+
+ # Make an object to represent the XML-RPC server.
+ server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
+
+ begin
+ # Call the remote server and get our result
+ result = server.call("sample.sumAndDifference", 5, 3)
+
+ sum = result["sum"]
+ difference = result["difference"]
+
+ puts "Sum: #{sum}, Difference: #{difference}"
+
+ rescue XMLRPC::FaultException => e
+ puts "Error: "
+ puts e.faultCode
+ puts e.faultString
+ end
+
+==== by calling "call2" which returns a boolean
+
+ require "xmlrpc/client"
+
+ # Make an object to represent the XML-RPC server.
+ server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
+
+ # Call the remote server and get our result
+ ok, result = server.call2("sample.sumAndDifference", 5, 3)
+
+ if ok
+ sum = result["sum"]
+ difference = result["difference"]
+
+ puts "Sum: #{sum}, Difference: #{difference}"
+ else
+ puts "Error: "
+ puts result.faultCode
+ puts result.faultString
+ end
+
+=== Client using Proxy
+
+You can create a +Proxy+ object onto which you can call methods. This way it
+looks nicer. Both forms, _call_ and _call2_ are supported through _proxy_ and
+<i>proxy2</i>. You can additionally give arguments to the Proxy, which will be
+given to each XML-RPC call using that Proxy.
+
+ require "xmlrpc/client"
+
+ # Make an object to represent the XML-RPC server.
+ server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
+
+ # Create a Proxy object
+ sample = server.proxy("sample")
+
+ # Call the remote server and get our result
+ result = sample.sumAndDifference(5,3)
+
+ sum = result["sum"]
+ difference = result["difference"]
+
+ puts "Sum: #{sum}, Difference: #{difference}"
+
+=== CGI-based Server
+
+There are also two ways to define handler, the first is
+like C/PHP, the second like Java, of course both ways
+can be mixed:
+
+==== C/PHP-like (handler functions)
+
+ require "xmlrpc/server"
+
+ s = XMLRPC::CGIServer.new
+
+ s.add_handler("sample.sumAndDifference") do |a,b|
+ { "sum" => a + b, "difference" => a - b }
+ end
+
+ s.serve
+
+==== Java-like (handler classes)
+
+ require "xmlrpc/server"
+
+ s = XMLRPC::CGIServer.new
+
+ class MyHandler
+ def sumAndDifference(a, b)
+ { "sum" => a + b, "difference" => a - b }
+ end
+ end
+
+ # NOTE: Security Hole (read below)!!!
+ s.add_handler("sample", MyHandler.new)
+ s.serve
+
+
+To return a fault-structure you have to raise an FaultException e.g.:
+
+ raise XMLRPC::FaultException.new(3, "division by Zero")
+
+===== Security Note
+
+From Brian Candler:
+
+ Above code sample has an extremely nasty security hole, in that you can now call
+ any method of 'MyHandler' remotely, including methods inherited from Object
+ and Kernel! For example, in the client code, you can use
+
+ puts server.call("sample.send","`","ls")
+
+ (backtick being the method name for running system processes). Needless to
+ say, 'ls' can be replaced with something else.
+
+ The version which binds proc objects (or the version presented below in the next section)
+ doesn't have this problem, but people may be tempted to use the second version because it's
+ so nice and 'Rubyesque'. I think it needs a big red disclaimer.
+
+
+From Michael:
+
+A solution is to undef insecure methods or to use (({XMLRPC::iPIMethods})) as shown below:
+
+ class MyHandler
+ def sumAndDifference(a, b)
+ { "sum" => a + b, "difference" => a - b }
+ end
+ end
+
+ # ... server initialization ...
+
+ s.add_handler(XMLRPC::iPIMethods("sample"), MyHandler.new)
+
+ # ...
+
+This adds only public instance methods explicitly declared in class MyHandler
+(and not those inherited from any other class).
+
+==== With interface declarations
+
+Code sample from the book Ruby Developer's Guide:
+
+ require "xmlrpc/server"
+
+ class Num
+ INTERFACE = XMLRPC::interface("num") {
+ meth 'int add(int, int)', 'Add two numbers', 'add'
+ meth 'int div(int, int)', 'Divide two numbers'
+ }
+
+ def add(a, b) a + b end
+ def div(a, b) a / b end
+ end
+
+
+ s = XMLRPC::CGIServer.new
+ s.add_handler(Num::INTERFACE, Num.new)
+ s.serve
+
+=== Standalone server
+
+Same as CGI-based server, only that the line
+
+ server = XMLRPC::CGIServer.new
+
+must be changed to
+
+ server = XMLRPC::Server.new(8080)
+
+if you want a server listening on port 8080.
+The rest is the same.
+
+=== Choosing a different XML Parser or XML Writer
+
+The examples above all use the default parser (which is now since 1.8
+REXMLStreamParser) and a default XML writer. If you want to use a different
+XML parser, then you have to call the <i>set_parser</i> method of
+<tt>XMLRPC::Client</tt> instances or instances of subclasses of
+<tt>XMLRPC::BasicServer</tt> or by editing xmlrpc/config.rb.
+
+Client Example:
+
+ # ...
+ server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php")
+ server.set_parser(XMLRPC::XMLParser::XMLParser.new)
+ # ...
+
+Server Example:
+
+ # ...
+ s = XMLRPC::CGIServer.new
+ s.set_parser(XMLRPC::XMLParser::XMLStreamParser.new)
+ # ...
+
+or:
+
+ # ...
+ server = XMLRPC::Server.new(8080)
+ server.set_parser(XMLRPC::XMLParser::NQXMLParser.new)
+ # ...
+
+
+Note that XMLStreamParser is incredible faster (and uses less memory) than any
+other parser and scales well for large documents. For example for a 0.5 MB XML
+document with many tags, XMLStreamParser is ~350 (!) times faster than
+NQXMLTreeParser and still ~18 times as fast as XMLTreeParser.
+
+You can change the XML-writer by calling method <i>set_writer</i>.