diff options
Diffstat (limited to 'lib/xmlrpc/server.rb')
-rw-r--r-- | lib/xmlrpc/server.rb | 190 |
1 files changed, 95 insertions, 95 deletions
diff --git a/lib/xmlrpc/server.rb b/lib/xmlrpc/server.rb index 131173fa70..6b5c5d4253 100644 --- a/lib/xmlrpc/server.rb +++ b/lib/xmlrpc/server.rb @@ -14,23 +14,23 @@ Released under the same term of license as Ruby. = XMLRPC::BasicServer == Description Is the base class for all XML-RPC server-types (CGI, standalone). -You can add handler and set a default handler. +You can add handler and set a default handler. Do not use this server, as this is/should be an abstract class. === How the method to call is found -The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is -compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)). -A handler is only called if it accepts the number of arguments, otherwise the search -for another handler will go on. When at the end no handler was found, +The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is +compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)). +A handler is only called if it accepts the number of arguments, otherwise the search +for another handler will go on. When at the end no handler was found, the ((<default_handler|XMLRPC::BasicServer#set_default_handler>)) will be called. With this technique it is possible to do overloading by number of parameters, but only for (({Proc})) handler, because you cannot define two methods of the same name in -the same class. +the same class. == Class Methods --- XMLRPC::BasicServer.new( class_delim="." ) - Creates a new (({XMLRPC::BasicServer})) instance, which should not be + Creates a new (({XMLRPC::BasicServer})) instance, which should not be done, because (({XMLRPC::BasicServer})) is an abstract class. This method should be called from a subclass indirectly by a (({super})) call in the method (({initialize})). The paramter ((|class_delim|)) is used @@ -40,24 +40,24 @@ the same class. == Instance Methods --- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock } Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method. - Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified, - where ((|signature|)) is either an Array containing strings each representing a type of it's - signature (the first is the return value) or an Array of Arrays if the method has multiple + Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified, + where ((|signature|)) is either an Array containing strings each representing a type of it's + signature (the first is the return value) or an Array of Arrays if the method has multiple signatures. Value type-names are "int, boolean, double, string, dateTime.iso8601, base64, array, struct". Parameter ((|help|)) is a String with informations about how to call this method etc. A handler method or code-block can return the types listed at - ((<XMLRPC::Client#call|URL:client.html#index:0>)). - When a method fails, it can tell it the client by throwing an + ((<XMLRPC::Client#call|URL:client.html#index:0>)). + When a method fails, it can tell it the client by throwing an (({XMLRPC::FaultException})) like in this example: s.add_handler("michael.div") do |a,b| if b == 0 raise XMLRPC::FaultException.new(1, "division by zero") else - a / b + a / b end - end + end The client gets in the case of (({b==0})) an object back of type (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|)) field. @@ -67,10 +67,10 @@ the same class. To add an object write: server.add_handler("michael", MyHandlerClass.new) All public methods of (({MyHandlerClass})) are accessible to - the XML-RPC clients by (('michael."name of method"')). This is - where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>)) - has it's role, a XML-RPC method-name is defined by - ((|prefix|)) + ((|class_delim|)) + (('"name of method"')). + the XML-RPC clients by (('michael."name of method"')). This is + where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>)) + has it's role, a XML-RPC method-name is defined by + ((|prefix|)) + ((|class_delim|)) + (('"name of method"')). --- XMLRPC::BasicServer#add_handler( interface, obj ) This is the third form of ((<add_handler|XMLRPC::BasicServer#add_handler>)). @@ -91,11 +91,11 @@ the same class. It is a (({Proc})) object or (({nil})). --- XMLRPC::BasicServer#set_default_handler ( &handler ) - Sets ((|handler|)) as the default-handler, which is called when + Sets ((|handler|)) as the default-handler, which is called when no handler for a method-name is found. ((|handler|)) is a code-block. The default-handler is called with the (XML-RPC) method-name as first argument, and the other arguments are the parameters given by the client-call. - + If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a XMLRPC::FaultException saying "method missing". @@ -103,7 +103,7 @@ the same class. --- XMLRPC::BasicServer#set_writer( writer ) Sets the XML writer to use for generating XML output. Should be an instance of a class from module (({XMLRPC::XMLWriter})). - If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. + If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used. --- XMLRPC::BasicServer#set_parser( parser ) Sets the XML parser to use for parsing XML documents. @@ -111,7 +111,7 @@ the same class. If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used. --- XMLRPC::BasicServer#add_introspection - Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp", + Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp", where only the first one works. --- XMLRPC::BasicServer#add_multicall @@ -123,7 +123,7 @@ the same class. --- XMLRPC::BasicServer#set_service_hook ( &handler ) A service-hook is called for each service request (RPC). You can use a service-hook for example to wrap existing methods and catch exceptions of them or - convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter + convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter ((|handler|)) . The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})). @@ -132,7 +132,7 @@ the same class. server.set_service_hook {|obj, *args| begin ret = obj.call(*args) # call the original service-method - # could convert the return value + # could convert the return value resuce # rescue exceptions end @@ -157,7 +157,7 @@ class BasicServer include ParserWriterChooseMixin include ParseContentType - ERR_METHOD_MISSING = 1 + ERR_METHOD_MISSING = 1 ERR_UNCAUGHT_EXCEPTION = 2 ERR_MC_WRONG_PARAM = 3 ERR_MC_MISSING_PARAMS = 4 @@ -169,7 +169,7 @@ class BasicServer def initialize(class_delim=".") @handler = [] - @default_handler = nil + @default_handler = nil @service_hook = nil @class_delim = class_delim @@ -183,7 +183,7 @@ class BasicServer def add_handler(prefix, obj_or_signature=nil, help=nil, &block) if block_given? # proc-handler - @handler << [prefix, block, obj_or_signature, help] + @handler << [prefix, block, obj_or_signature, help] else if prefix.kind_of? String # class-handler @@ -208,7 +208,7 @@ class BasicServer @service_hook = handler self end - + def get_default_handler @default_handler end @@ -216,18 +216,18 @@ class BasicServer def set_default_handler (&handler) @default_handler = handler self - end + end def add_multicall add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs| - unless arrStructs.is_a? Array + unless arrStructs.is_a? Array raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array") end arrStructs.collect {|call| if call.is_a? Hash methodName = call["methodName"] - params = call["params"] + params = call["params"] if params.nil? multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params") @@ -246,16 +246,16 @@ class BasicServer [val] else # exception - multicall_fault(val.faultCode, val.faultString) + multicall_fault(val.faultCode, val.faultString) end end end - end - + end + else multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct") end - } + } end # end add_handler self end @@ -284,7 +284,7 @@ class BasicServer sig.each {|s| sigs << s} else # sig is a single signature, e.g. ["array"] - sigs << sig + sigs << sig end end end @@ -292,11 +292,11 @@ class BasicServer end add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth| - help = nil + help = nil @handler.each do |name, obj, sig, hlp| - if obj.kind_of? Proc and name == meth + if obj.kind_of? Proc and name == meth help = hlp - break + break end end help || "" @@ -306,18 +306,18 @@ class BasicServer end - + def process(data) - method, params = parser().parseMethodCall(data) + method, params = parser().parseMethodCall(data) handle(method, *params) end - + private # -------------------------------------------------------------- def multicall_fault(nr, str) {"faultCode" => nr, "faultString" => str} end - + # # method dispatch # @@ -333,17 +333,17 @@ class BasicServer if check_arity(obj, args.size) if @service_hook.nil? - return obj.call(*args) + return obj.call(*args) else return @service_hook.call(obj, *args) end end - end - + end + if @default_handler.nil? raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, "Method #{methodname} missing or wrong number of parameters!") else - @default_handler.call(methodname, *args) + @default_handler.call(methodname, *args) end end @@ -357,7 +357,7 @@ class BasicServer if ary >= 0 n_args == ary else - n_args >= (ary+1).abs + n_args >= (ary+1).abs end end @@ -366,8 +366,8 @@ class BasicServer def call_method(methodname, *args) begin [true, dispatch(methodname, *args)] - rescue XMLRPC::FaultException => e - [false, e] + rescue XMLRPC::FaultException => e + [false, e] rescue Exception => e [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")] end @@ -388,8 +388,8 @@ end = XMLRPC::CGIServer == Synopsis require "xmlrpc/server" - - s = XMLRPC::CGIServer.new + + s = XMLRPC::CGIServer.new s.add_handler("michael.add") do |a,b| a + b @@ -399,15 +399,15 @@ end if b == 0 raise XMLRPC::FaultException.new(1, "division by zero") else - a / b + a / b end - end + end s.set_default_handler do |name, *args| raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + " or wrong number of parameters!") end - + s.serve == Description @@ -419,7 +419,7 @@ Implements a CGI-based XML-RPC server. == Class Methods --- XMLRPC::CGIServer.new( *a ) Creates a new (({XMLRPC::CGIServer})) instance. All parameters given - are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create + are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes no sense. @@ -427,7 +427,7 @@ Implements a CGI-based XML-RPC server. --- XMLRPC::CGIServer#serve Call this after you have added all you handlers to the server. This method processes a XML-RPC methodCall and sends the answer - back to the client. + back to the client. Make sure that you don't write to standard-output in a handler, or in any other part of your program, this would case a CGI-based server to fail! =end @@ -443,14 +443,14 @@ class CGIServer < BasicServer def initialize(*a) super(*a) end - + def serve catch(:exit_serve) { length = ENV['CONTENT_LENGTH'].to_i - http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST" + http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST" http_error(400, "Bad Request") unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml" - http_error(411, "Length Required") unless length > 0 + http_error(411, "Length Required") unless length > 0 # TODO: do we need a call to binmode? $stdin.binmode if $stdin.respond_to? :binmode @@ -467,7 +467,7 @@ class CGIServer < BasicServer def http_error(status, message) err = "#{status} #{message}" - msg = <<-"MSGEND" + msg = <<-"MSGEND" <html> <head> <title>#{err}</title> @@ -487,7 +487,7 @@ class CGIServer < BasicServer h = {} header.each {|key, value| h[key.to_s.capitalize] = value} h['Status'] ||= "200 OK" - h['Content-length'] ||= body.size.to_s + h['Content-length'] ||= body.size.to_s str = "" h.each {|key, value| str << "#{key}: #{value}\r\n"} @@ -507,7 +507,7 @@ Use it in the same way as CGIServer! == Superclass ((<XMLRPC::BasicServer>)) -=end +=end class ModRubyServer < BasicServer @@ -523,9 +523,9 @@ class ModRubyServer < BasicServer length = header['Content-length'].to_i - http_error(405, "Method Not Allowed") unless @ap.request_method == "POST" + http_error(405, "Method Not Allowed") unless @ap.request_method == "POST" http_error(400, "Bad Request") unless parse_content_type(header['Content-type']).first == "text/xml" - http_error(411, "Length Required") unless length > 0 + http_error(411, "Length Required") unless length > 0 # TODO: do we need a call to binmode? @ap.binmode @@ -542,7 +542,7 @@ class ModRubyServer < BasicServer def http_error(status, message) err = "#{status} #{message}" - msg = <<-"MSGEND" + msg = <<-"MSGEND" <html> <head> <title>#{err}</title> @@ -562,12 +562,12 @@ class ModRubyServer < BasicServer h = {} header.each {|key, value| h[key.to_s.capitalize] = value} h['Status'] ||= "200 OK" - h['Content-length'] ||= body.size.to_s + h['Content-length'] ||= body.size.to_s h.each {|key, value| @ap.headers_out[key] = value } - @ap.content_type = h["Content-type"] - @ap.status = status.to_i - @ap.send_http_header + @ap.content_type = h["Content-type"] + @ap.status = status.to_i + @ap.send_http_header @ap.print body end @@ -578,8 +578,8 @@ end = XMLRPC::Server == Synopsis require "xmlrpc/server" - - s = XMLRPC::Server.new(8080) + + s = XMLRPC::Server.new(8080) s.add_handler("michael.add") do |a,b| a + b @@ -589,15 +589,15 @@ end if b == 0 raise XMLRPC::FaultException.new(1, "division by zero") else - a / b + a / b end - end + end s.set_default_handler do |name, *args| raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + " or wrong number of parameters!") end - + s.serve == Description @@ -610,13 +610,13 @@ program. == Class Methods --- XMLRPC::Server.new( port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a ) Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on - port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost. + port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost. The server is not started, to start it you have to call ((<serve|XMLRPC::Server#serve>)). Parameters ((|audit|)) and ((|debug|)) are obsolete! - All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)). - + All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)). + == Instance Methods --- XMLRPC::Server#serve Call this after you have added all you handlers to the server. @@ -624,7 +624,7 @@ program. --- XMLRPC::Server#shutdown Stops and shuts the server down. - + =end class WEBrickServlet < BasicServer; end # forward declaration @@ -634,22 +634,22 @@ class Server < WEBrickServlet def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a) super(*a) require 'webrick' - @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections, + @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections, :Logger => WEBrick::Log.new(stdlog)) @server.mount("/", self) end - + def serve signals = %w[INT TERM HUP] & Signal.list.keys signals.each { |signal| trap(signal) { @server.shutdown } } @server.start end - + def shutdown @server.shutdown end - + end =begin @@ -668,16 +668,16 @@ end if b == 0 raise XMLRPC::FaultException.new(1, "division by zero") else - a / b + a / b end - end + end s.set_default_handler do |name, *args| raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + " or wrong number of parameters!") end - httpserver = WEBrick::HTTPServer.new(:Port => 8080) + httpserver = WEBrick::HTTPServer.new(:Port => 8080) httpserver.mount("/RPC2", s) trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows httpserver.start @@ -691,7 +691,7 @@ end --- XMLRPC::WEBrickServlet#get_valid_ip Return the via method ((<set_valid_ip|XMLRPC::Server#set_valid_ip>)) specified valid IP addresses. - + == Description Implements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework. @@ -707,10 +707,10 @@ class WEBrickServlet < BasicServer @valid_ip = nil end - # deprecated from WEBrick/1.2.2. + # deprecated from WEBrick/1.2.2. # but does not break anything. def require_path_info? - false + false end def get_instance(config, *options) @@ -732,7 +732,7 @@ class WEBrickServlet < BasicServer def service(request, response) - if @valid_ip + if @valid_ip raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip } end @@ -741,9 +741,9 @@ class WEBrickServlet < BasicServer "unsupported method `#{request.request_method}'." end - if parse_content_type(request['Content-type']).first != "text/xml" + if parse_content_type(request['Content-type']).first != "text/xml" raise WEBrick::HTTPStatus::BadRequest - end + end length = (request['Content-length'] || 0).to_i @@ -756,14 +756,14 @@ class WEBrickServlet < BasicServer end resp = process(data) - if resp.nil? or resp.size <= 0 + if resp.nil? or resp.size <= 0 raise WEBrick::HTTPStatus::InternalServerError end response.status = 200 response['Content-Length'] = resp.size response['Content-Type'] = "text/xml; charset=utf-8" - response.body = resp + response.body = resp end end @@ -773,6 +773,6 @@ end # module XMLRPC =begin = History - $Id$ + $Id$ =end |