/tools/Ruby/lib/ruby/1.8/xmlrpc/server.rb

http://github.com/agross/netopenspace · Ruby · 782 lines · 351 code · 108 blank · 323 comment · 52 complexity · 5ab0fd849ba51e84a7b3b098a772d544 MD5 · raw file

  1. =begin
  2. = xmlrpc/server.rb
  3. Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de)
  4. Released under the same term of license as Ruby.
  5. = Classes
  6. * ((<XMLRPC::BasicServer>))
  7. * ((<XMLRPC::CGIServer>))
  8. * ((<XMLRPC::ModRubyServer>))
  9. * ((<XMLRPC::Server>))
  10. * ((<XMLRPC::WEBrickServlet>))
  11. = XMLRPC::BasicServer
  12. == Description
  13. Is the base class for all XML-RPC server-types (CGI, standalone).
  14. You can add handler and set a default handler.
  15. Do not use this server, as this is/should be an abstract class.
  16. === How the method to call is found
  17. The arity (number of accepted arguments) of a handler (method or (({Proc})) object) is
  18. compared to the given arguments submitted by the client for a RPC ((-Remote Procedure Call-)).
  19. A handler is only called if it accepts the number of arguments, otherwise the search
  20. for another handler will go on. When at the end no handler was found,
  21. the ((<default_handler|XMLRPC::BasicServer#set_default_handler>)) will be called.
  22. With this technique it is possible to do overloading by number of parameters, but
  23. only for (({Proc})) handler, because you cannot define two methods of the same name in
  24. the same class.
  25. == Class Methods
  26. --- XMLRPC::BasicServer.new( class_delim="." )
  27. Creates a new (({XMLRPC::BasicServer})) instance, which should not be
  28. done, because (({XMLRPC::BasicServer})) is an abstract class. This
  29. method should be called from a subclass indirectly by a (({super})) call
  30. in the method (({initialize})). The paramter ((|class_delim|)) is used
  31. in ((<add_handler|XMLRPC::BasicServer#add_handler>)) when an object is
  32. added as handler, to delimit the object-prefix and the method-name.
  33. == Instance Methods
  34. --- XMLRPC::BasicServer#add_handler( name, signature=nil, help=nil ) { aBlock }
  35. Adds ((|aBlock|)) to the list of handlers, with ((|name|)) as the name of the method.
  36. Parameters ((|signature|)) and ((|help|)) are used by the Introspection method if specified,
  37. where ((|signature|)) is either an Array containing strings each representing a type of it's
  38. signature (the first is the return value) or an Array of Arrays if the method has multiple
  39. signatures. Value type-names are "int, boolean, double, string, dateTime.iso8601, base64, array, struct".
  40. Parameter ((|help|)) is a String with informations about how to call this method etc.
  41. A handler method or code-block can return the types listed at
  42. ((<XMLRPC::Client#call|URL:client.html#index:0>)).
  43. When a method fails, it can tell it the client by throwing an
  44. (({XMLRPC::FaultException})) like in this example:
  45. s.add_handler("michael.div") do |a,b|
  46. if b == 0
  47. raise XMLRPC::FaultException.new(1, "division by zero")
  48. else
  49. a / b
  50. end
  51. end
  52. The client gets in the case of (({b==0})) an object back of type
  53. (({XMLRPC::FaultException})) that has a ((|faultCode|)) and ((|faultString|))
  54. field.
  55. --- XMLRPC::BasicServer#add_handler( prefix, obj )
  56. This is the second form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
  57. To add an object write:
  58. server.add_handler("michael", MyHandlerClass.new)
  59. All public methods of (({MyHandlerClass})) are accessible to
  60. the XML-RPC clients by (('michael."name of method"')). This is
  61. where the ((|class_delim|)) in ((<new|XMLRPC::BasicServer.new>))
  62. has it's role, a XML-RPC method-name is defined by
  63. ((|prefix|)) + ((|class_delim|)) + (('"name of method"')).
  64. --- XMLRPC::BasicServer#add_handler( interface, obj )
  65. This is the third form of ((<add_handler|XMLRPC::BasicServer#add_handler>)).
  66. Use (({XMLRPC::interface})) to generate an ServiceInterface object, which
  67. represents an interface (with signature and help text) for a handler class.
  68. Parameter ((|interface|)) must be of type (({XMLRPC::ServiceInterface})).
  69. Adds all methods of ((|obj|)) which are defined in ((|interface|)) to the
  70. server.
  71. This is the recommended way of adding services to a server!
  72. --- XMLRPC::BasicServer#get_default_handler
  73. Returns the default-handler, which is called when no handler for
  74. a method-name is found.
  75. It is a (({Proc})) object or (({nil})).
  76. --- XMLRPC::BasicServer#set_default_handler ( &handler )
  77. Sets ((|handler|)) as the default-handler, which is called when
  78. no handler for a method-name is found. ((|handler|)) is a code-block.
  79. The default-handler is called with the (XML-RPC) method-name as first argument, and
  80. the other arguments are the parameters given by the client-call.
  81. If no block is specified the default of (({XMLRPC::BasicServer})) is used, which raises a
  82. XMLRPC::FaultException saying "method missing".
  83. --- XMLRPC::BasicServer#set_writer( writer )
  84. Sets the XML writer to use for generating XML output.
  85. Should be an instance of a class from module (({XMLRPC::XMLWriter})).
  86. If this method is not called, then (({XMLRPC::Config::DEFAULT_WRITER})) is used.
  87. --- XMLRPC::BasicServer#set_parser( parser )
  88. Sets the XML parser to use for parsing XML documents.
  89. Should be an instance of a class from module (({XMLRPC::XMLParser})).
  90. If this method is not called, then (({XMLRPC::Config::DEFAULT_PARSER})) is used.
  91. --- XMLRPC::BasicServer#add_introspection
  92. Adds the introspection handlers "system.listMethods", "system.methodSignature" and "system.methodHelp",
  93. where only the first one works.
  94. --- XMLRPC::BasicServer#add_multicall
  95. Adds the multi-call handler "system.multicall".
  96. --- XMLRPC::BasicServer#get_service_hook
  97. Returns the service-hook, which is called on each service request (RPC) unless it's (({nil})).
  98. --- XMLRPC::BasicServer#set_service_hook ( &handler )
  99. A service-hook is called for each service request (RPC).
  100. You can use a service-hook for example to wrap existing methods and catch exceptions of them or
  101. convert values to values recognized by XMLRPC. You can disable it by passing (({nil})) as parameter
  102. ((|handler|)) .
  103. The service-hook is called with a (({Proc})) object and with the parameters for this (({Proc})).
  104. An example:
  105. server.set_service_hook {|obj, *args|
  106. begin
  107. ret = obj.call(*args) # call the original service-method
  108. # could convert the return value
  109. resuce
  110. # rescue exceptions
  111. end
  112. }
  113. =end
  114. require "xmlrpc/parser"
  115. require "xmlrpc/create"
  116. require "xmlrpc/config"
  117. require "xmlrpc/utils" # ParserWriterChooseMixin
  118. module XMLRPC
  119. class BasicServer
  120. include ParserWriterChooseMixin
  121. include ParseContentType
  122. ERR_METHOD_MISSING = 1
  123. ERR_UNCAUGHT_EXCEPTION = 2
  124. ERR_MC_WRONG_PARAM = 3
  125. ERR_MC_MISSING_PARAMS = 4
  126. ERR_MC_MISSING_METHNAME = 5
  127. ERR_MC_RECURSIVE_CALL = 6
  128. ERR_MC_WRONG_PARAM_PARAMS = 7
  129. ERR_MC_EXPECTED_STRUCT = 8
  130. def initialize(class_delim=".")
  131. @handler = []
  132. @default_handler = nil
  133. @service_hook = nil
  134. @class_delim = class_delim
  135. @create = nil
  136. @parser = nil
  137. add_multicall if Config::ENABLE_MULTICALL
  138. add_introspection if Config::ENABLE_INTROSPECTION
  139. end
  140. def add_handler(prefix, obj_or_signature=nil, help=nil, &block)
  141. if block_given?
  142. # proc-handler
  143. @handler << [prefix, block, obj_or_signature, help]
  144. else
  145. if prefix.kind_of? String
  146. # class-handler
  147. raise ArgumentError, "Expected non-nil value" if obj_or_signature.nil?
  148. @handler << [prefix + @class_delim, obj_or_signature]
  149. elsif prefix.kind_of? XMLRPC::Service::BasicInterface
  150. # class-handler with interface
  151. # add all methods
  152. @handler += prefix.get_methods(obj_or_signature, @class_delim)
  153. else
  154. raise ArgumentError, "Wrong type for parameter 'prefix'"
  155. end
  156. end
  157. self
  158. end
  159. def get_service_hook
  160. @service_hook
  161. end
  162. def set_service_hook(&handler)
  163. @service_hook = handler
  164. self
  165. end
  166. def get_default_handler
  167. @default_handler
  168. end
  169. def set_default_handler (&handler)
  170. @default_handler = handler
  171. self
  172. end
  173. def add_multicall
  174. add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs|
  175. unless arrStructs.is_a? Array
  176. raise XMLRPC::FaultException.new(ERR_MC_WRONG_PARAM, "system.multicall expects an array")
  177. end
  178. arrStructs.collect {|call|
  179. if call.is_a? Hash
  180. methodName = call["methodName"]
  181. params = call["params"]
  182. if params.nil?
  183. multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params")
  184. elsif methodName.nil?
  185. multicall_fault(ERR_MC_MISSING_METHNAME, "Missing methodName")
  186. else
  187. if methodName == "system.multicall"
  188. multicall_fault(ERR_MC_RECURSIVE_CALL, "Recursive system.multicall forbidden")
  189. else
  190. unless params.is_a? Array
  191. multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, "Parameter params have to be an Array")
  192. else
  193. ok, val = call_method(methodName, *params)
  194. if ok
  195. # correct return value
  196. [val]
  197. else
  198. # exception
  199. multicall_fault(val.faultCode, val.faultString)
  200. end
  201. end
  202. end
  203. end
  204. else
  205. multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct")
  206. end
  207. }
  208. end # end add_handler
  209. self
  210. end
  211. def add_introspection
  212. add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do
  213. methods = []
  214. @handler.each do |name, obj|
  215. if obj.kind_of? Proc
  216. methods << name
  217. else
  218. obj.class.public_instance_methods(false).each do |meth|
  219. methods << "#{name}#{meth}"
  220. end
  221. end
  222. end
  223. methods
  224. end
  225. add_handler("system.methodSignature", %w(array string), "Returns method signature") do |meth|
  226. sigs = []
  227. @handler.each do |name, obj, sig|
  228. if obj.kind_of? Proc and sig != nil and name == meth
  229. if sig[0].kind_of? Array
  230. # sig contains multiple signatures, e.g. [["array"], ["array", "string"]]
  231. sig.each {|s| sigs << s}
  232. else
  233. # sig is a single signature, e.g. ["array"]
  234. sigs << sig
  235. end
  236. end
  237. end
  238. sigs.uniq! || sigs # remove eventually duplicated signatures
  239. end
  240. add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth|
  241. help = nil
  242. @handler.each do |name, obj, sig, hlp|
  243. if obj.kind_of? Proc and name == meth
  244. help = hlp
  245. break
  246. end
  247. end
  248. help || ""
  249. end
  250. self
  251. end
  252. def process(data)
  253. method, params = parser().parseMethodCall(data)
  254. handle(method, *params)
  255. end
  256. private # --------------------------------------------------------------
  257. def multicall_fault(nr, str)
  258. {"faultCode" => nr, "faultString" => str}
  259. end
  260. #
  261. # method dispatch
  262. #
  263. def dispatch(methodname, *args)
  264. for name, obj in @handler
  265. if obj.kind_of? Proc
  266. next unless methodname == name
  267. else
  268. next unless methodname =~ /^#{name}(.+)$/
  269. next unless obj.respond_to? $1
  270. obj = obj.method($1)
  271. end
  272. if check_arity(obj, args.size)
  273. if @service_hook.nil?
  274. return obj.call(*args)
  275. else
  276. return @service_hook.call(obj, *args)
  277. end
  278. end
  279. end
  280. if @default_handler.nil?
  281. raise XMLRPC::FaultException.new(ERR_METHOD_MISSING, "Method #{methodname} missing or wrong number of parameters!")
  282. else
  283. @default_handler.call(methodname, *args)
  284. end
  285. end
  286. #
  287. # returns true, if the arity of "obj" matches
  288. #
  289. def check_arity(obj, n_args)
  290. ary = obj.arity
  291. if ary >= 0
  292. n_args == ary
  293. else
  294. n_args >= (ary+1).abs
  295. end
  296. end
  297. def call_method(methodname, *args)
  298. begin
  299. [true, dispatch(methodname, *args)]
  300. rescue XMLRPC::FaultException => e
  301. [false, e]
  302. rescue Exception => e
  303. [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")]
  304. end
  305. end
  306. #
  307. #
  308. #
  309. def handle(methodname, *args)
  310. create().methodResponse(*call_method(methodname, *args))
  311. end
  312. end
  313. =begin
  314. = XMLRPC::CGIServer
  315. == Synopsis
  316. require "xmlrpc/server"
  317. s = XMLRPC::CGIServer.new
  318. s.add_handler("michael.add") do |a,b|
  319. a + b
  320. end
  321. s.add_handler("michael.div") do |a,b|
  322. if b == 0
  323. raise XMLRPC::FaultException.new(1, "division by zero")
  324. else
  325. a / b
  326. end
  327. end
  328. s.set_default_handler do |name, *args|
  329. raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
  330. " or wrong number of parameters!")
  331. end
  332. s.serve
  333. == Description
  334. Implements a CGI-based XML-RPC server.
  335. == Superclass
  336. ((<XMLRPC::BasicServer>))
  337. == Class Methods
  338. --- XMLRPC::CGIServer.new( *a )
  339. Creates a new (({XMLRPC::CGIServer})) instance. All parameters given
  340. are by-passed to ((<XMLRPC::BasicServer.new>)). You can only create
  341. ((*one*)) (({XMLRPC::CGIServer})) instance, because more than one makes
  342. no sense.
  343. == Instance Methods
  344. --- XMLRPC::CGIServer#serve
  345. Call this after you have added all you handlers to the server.
  346. This method processes a XML-RPC methodCall and sends the answer
  347. back to the client.
  348. Make sure that you don't write to standard-output in a handler, or in
  349. any other part of your program, this would case a CGI-based server to fail!
  350. =end
  351. class CGIServer < BasicServer
  352. @@obj = nil
  353. def CGIServer.new(*a)
  354. @@obj = super(*a) if @@obj.nil?
  355. @@obj
  356. end
  357. def initialize(*a)
  358. super(*a)
  359. end
  360. def serve
  361. catch(:exit_serve) {
  362. length = ENV['CONTENT_LENGTH'].to_i
  363. http_error(405, "Method Not Allowed") unless ENV['REQUEST_METHOD'] == "POST"
  364. http_error(400, "Bad Request") unless parse_content_type(ENV['CONTENT_TYPE']).first == "text/xml"
  365. http_error(411, "Length Required") unless length > 0
  366. # TODO: do we need a call to binmode?
  367. $stdin.binmode if $stdin.respond_to? :binmode
  368. data = $stdin.read(length)
  369. http_error(400, "Bad Request") if data.nil? or data.size != length
  370. http_write(process(data), "Content-type" => "text/xml; charset=utf-8")
  371. }
  372. end
  373. private
  374. def http_error(status, message)
  375. err = "#{status} #{message}"
  376. msg = <<-"MSGEND"
  377. <html>
  378. <head>
  379. <title>#{err}</title>
  380. </head>
  381. <body>
  382. <h1>#{err}</h1>
  383. <p>Unexpected error occured while processing XML-RPC request!</p>
  384. </body>
  385. </html>
  386. MSGEND
  387. http_write(msg, "Status" => err, "Content-type" => "text/html")
  388. throw :exit_serve # exit from the #serve method
  389. end
  390. def http_write(body, header)
  391. h = {}
  392. header.each {|key, value| h[key.to_s.capitalize] = value}
  393. h['Status'] ||= "200 OK"
  394. h['Content-length'] ||= body.size.to_s
  395. str = ""
  396. h.each {|key, value| str << "#{key}: #{value}\r\n"}
  397. str << "\r\n#{body}"
  398. print str
  399. end
  400. end
  401. =begin
  402. = XMLRPC::ModRubyServer
  403. == Description
  404. Implements a XML-RPC server, which works with Apache mod_ruby.
  405. Use it in the same way as CGIServer!
  406. == Superclass
  407. ((<XMLRPC::BasicServer>))
  408. =end
  409. class ModRubyServer < BasicServer
  410. def initialize(*a)
  411. @ap = Apache::request
  412. super(*a)
  413. end
  414. def serve
  415. catch(:exit_serve) {
  416. header = {}
  417. @ap.headers_in.each {|key, value| header[key.capitalize] = value}
  418. length = header['Content-length'].to_i
  419. http_error(405, "Method Not Allowed") unless @ap.request_method == "POST"
  420. http_error(400, "Bad Request") unless parse_content_type(header['Content-type']).first == "text/xml"
  421. http_error(411, "Length Required") unless length > 0
  422. # TODO: do we need a call to binmode?
  423. @ap.binmode
  424. data = @ap.read(length)
  425. http_error(400, "Bad Request") if data.nil? or data.size != length
  426. http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8")
  427. }
  428. end
  429. private
  430. def http_error(status, message)
  431. err = "#{status} #{message}"
  432. msg = <<-"MSGEND"
  433. <html>
  434. <head>
  435. <title>#{err}</title>
  436. </head>
  437. <body>
  438. <h1>#{err}</h1>
  439. <p>Unexpected error occured while processing XML-RPC request!</p>
  440. </body>
  441. </html>
  442. MSGEND
  443. http_write(msg, status, "Status" => err, "Content-type" => "text/html")
  444. throw :exit_serve # exit from the #serve method
  445. end
  446. def http_write(body, status, header)
  447. h = {}
  448. header.each {|key, value| h[key.to_s.capitalize] = value}
  449. h['Status'] ||= "200 OK"
  450. h['Content-length'] ||= body.size.to_s
  451. h.each {|key, value| @ap.headers_out[key] = value }
  452. @ap.content_type = h["Content-type"]
  453. @ap.status = status.to_i
  454. @ap.send_http_header
  455. @ap.print body
  456. end
  457. end
  458. =begin
  459. = XMLRPC::Server
  460. == Synopsis
  461. require "xmlrpc/server"
  462. s = XMLRPC::Server.new(8080)
  463. s.add_handler("michael.add") do |a,b|
  464. a + b
  465. end
  466. s.add_handler("michael.div") do |a,b|
  467. if b == 0
  468. raise XMLRPC::FaultException.new(1, "division by zero")
  469. else
  470. a / b
  471. end
  472. end
  473. s.set_default_handler do |name, *args|
  474. raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
  475. " or wrong number of parameters!")
  476. end
  477. s.serve
  478. == Description
  479. Implements a standalone XML-RPC server. The method (({serve}))) is left if a SIGHUP is sent to the
  480. program.
  481. == Superclass
  482. ((<XMLRPC::WEBrickServlet>))
  483. == Class Methods
  484. --- XMLRPC::Server.new( port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a )
  485. Creates a new (({XMLRPC::Server})) instance, which is a XML-RPC server listening on
  486. port ((|port|)) and accepts requests for the host ((|host|)), which is by default only the localhost.
  487. The server is not started, to start it you have to call ((<serve|XMLRPC::Server#serve>)).
  488. Parameters ((|audit|)) and ((|debug|)) are obsolete!
  489. All additionally given parameters in ((|*a|)) are by-passed to ((<XMLRPC::BasicServer.new>)).
  490. == Instance Methods
  491. --- XMLRPC::Server#serve
  492. Call this after you have added all you handlers to the server.
  493. This method starts the server to listen for XML-RPC requests and answer them.
  494. --- XMLRPC::Server#shutdown
  495. Stops and shuts the server down.
  496. =end
  497. class WEBrickServlet < BasicServer; end # forward declaration
  498. class Server < WEBrickServlet
  499. def initialize(port=8080, host="127.0.0.1", maxConnections=4, stdlog=$stdout, audit=true, debug=true, *a)
  500. super(*a)
  501. require 'webrick'
  502. @server = WEBrick::HTTPServer.new(:Port => port, :BindAddress => host, :MaxClients => maxConnections,
  503. :Logger => WEBrick::Log.new(stdlog))
  504. @server.mount("/", self)
  505. end
  506. def serve
  507. if RUBY_PLATFORM =~ /mingw|mswin32/
  508. signals = [1]
  509. else
  510. signals = %w[INT TERM HUP]
  511. end
  512. signals.each { |signal| trap(signal) { @server.shutdown } }
  513. @server.start
  514. end
  515. def shutdown
  516. @server.shutdown
  517. end
  518. end
  519. =begin
  520. = XMLRPC::WEBrickServlet
  521. == Synopsis
  522. require "webrick"
  523. require "xmlrpc/server"
  524. s = XMLRPC::WEBrickServlet.new
  525. s.add_handler("michael.add") do |a,b|
  526. a + b
  527. end
  528. s.add_handler("michael.div") do |a,b|
  529. if b == 0
  530. raise XMLRPC::FaultException.new(1, "division by zero")
  531. else
  532. a / b
  533. end
  534. end
  535. s.set_default_handler do |name, *args|
  536. raise XMLRPC::FaultException.new(-99, "Method #{name} missing" +
  537. " or wrong number of parameters!")
  538. end
  539. httpserver = WEBrick::HTTPServer.new(:Port => 8080)
  540. httpserver.mount("/RPC2", s)
  541. trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows
  542. httpserver.start
  543. == Instance Methods
  544. --- XMLRPC::WEBrickServlet#set_valid_ip( *ip_addr )
  545. Specifies the valid IP addresses that are allowed to connect to the server.
  546. Each IP is either a (({String})) or a (({Regexp})).
  547. --- XMLRPC::WEBrickServlet#get_valid_ip
  548. Return the via method ((<set_valid_ip|XMLRPC::Server#set_valid_ip>)) specified
  549. valid IP addresses.
  550. == Description
  551. Implements a servlet for use with WEBrick, a pure Ruby (HTTP-) server framework.
  552. == Superclass
  553. ((<XMLRPC::BasicServer>))
  554. =end
  555. class WEBrickServlet < BasicServer
  556. def initialize(*a)
  557. super
  558. require "webrick/httpstatus"
  559. @valid_ip = nil
  560. end
  561. # deprecated from WEBrick/1.2.2.
  562. # but does not break anything.
  563. def require_path_info?
  564. false
  565. end
  566. def get_instance(config, *options)
  567. # TODO: set config & options
  568. self
  569. end
  570. def set_valid_ip(*ip_addr)
  571. if ip_addr.size == 1 and ip_addr[0].nil?
  572. @valid_ip = nil
  573. else
  574. @valid_ip = ip_addr
  575. end
  576. end
  577. def get_valid_ip
  578. @valid_ip
  579. end
  580. def service(request, response)
  581. if @valid_ip
  582. raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip }
  583. end
  584. if request.request_method != "POST"
  585. raise WEBrick::HTTPStatus::MethodNotAllowed,
  586. "unsupported method `#{request.request_method}'."
  587. end
  588. if parse_content_type(request['Content-type']).first != "text/xml"
  589. raise WEBrick::HTTPStatus::BadRequest
  590. end
  591. length = (request['Content-length'] || 0).to_i
  592. raise WEBrick::HTTPStatus::LengthRequired unless length > 0
  593. data = request.body
  594. if data.nil? or data.size != length
  595. raise WEBrick::HTTPStatus::BadRequest
  596. end
  597. resp = process(data)
  598. if resp.nil? or resp.size <= 0
  599. raise WEBrick::HTTPStatus::InternalServerError
  600. end
  601. response.status = 200
  602. response['Content-Length'] = resp.size
  603. response['Content-Type'] = "text/xml; charset=utf-8"
  604. response.body = resp
  605. end
  606. end
  607. end # module XMLRPC
  608. =begin
  609. = History
  610. $Id: server.rb 22461 2009-02-20 09:06:53Z shyouhei $
  611. =end