From 0f5050c513d616dfcb5a0eee9549e4d3d5061414 Mon Sep 17 00:00:00 2001 From: hsbt Date: Mon, 16 May 2016 02:41:11 +0000 Subject: * lib/xmlrpc.rb, lib/xmlrpc/*, test/xmlrpc: XMLRPC is bundled gem on Ruby 2.4. [Feature #12160][ruby-core:74239] * gems/bundled_gems: ditto. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55013 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 7 + gems/bundled_gems | 1 + lib/xmlrpc.rb | 291 -------------- lib/xmlrpc/base64.rb | 63 --- lib/xmlrpc/client.rb | 629 ------------------------------ lib/xmlrpc/config.rb | 39 -- lib/xmlrpc/create.rb | 287 -------------- lib/xmlrpc/datetime.rb | 130 ------- lib/xmlrpc/marshal.rb | 67 ---- lib/xmlrpc/parser.rb | 642 ------------------------------ lib/xmlrpc/server.rb | 708 ---------------------------------- lib/xmlrpc/utils.rb | 172 --------- test/xmlrpc/data/blog.xml | 18 - test/xmlrpc/data/bug_bool.expected | 3 - test/xmlrpc/data/bug_bool.xml | 8 - test/xmlrpc/data/bug_cdata.expected | 3 - test/xmlrpc/data/bug_cdata.xml | 8 - test/xmlrpc/data/bug_covert.expected | 10 - test/xmlrpc/data/bug_covert.xml | 6 - test/xmlrpc/data/datetime_iso8601.xml | 8 - test/xmlrpc/data/fault.xml | 16 - test/xmlrpc/data/value.expected | 7 - test/xmlrpc/data/value.xml | 22 -- test/xmlrpc/data/xml1.expected | 243 ------------ test/xmlrpc/data/xml1.xml | 1 - test/xmlrpc/htpasswd | 2 - test/xmlrpc/test_client.rb | 323 ---------------- test/xmlrpc/test_cookie.rb | 97 ----- test/xmlrpc/test_datetime.rb | 162 -------- test/xmlrpc/test_features.rb | 51 --- test/xmlrpc/test_marshal.rb | 111 ------ test/xmlrpc/test_parser.rb | 94 ----- test/xmlrpc/test_webrick_server.rb | 136 ------- test/xmlrpc/webrick_testing.rb | 61 --- 34 files changed, 8 insertions(+), 4418 deletions(-) delete mode 100644 lib/xmlrpc.rb delete mode 100644 lib/xmlrpc/base64.rb delete mode 100644 lib/xmlrpc/client.rb delete mode 100644 lib/xmlrpc/config.rb delete mode 100644 lib/xmlrpc/create.rb delete mode 100644 lib/xmlrpc/datetime.rb delete mode 100644 lib/xmlrpc/marshal.rb delete mode 100644 lib/xmlrpc/parser.rb delete mode 100644 lib/xmlrpc/server.rb delete mode 100644 lib/xmlrpc/utils.rb delete mode 100644 test/xmlrpc/data/blog.xml delete mode 100644 test/xmlrpc/data/bug_bool.expected delete mode 100644 test/xmlrpc/data/bug_bool.xml delete mode 100644 test/xmlrpc/data/bug_cdata.expected delete mode 100644 test/xmlrpc/data/bug_cdata.xml delete mode 100644 test/xmlrpc/data/bug_covert.expected delete mode 100644 test/xmlrpc/data/bug_covert.xml delete mode 100644 test/xmlrpc/data/datetime_iso8601.xml delete mode 100644 test/xmlrpc/data/fault.xml delete mode 100644 test/xmlrpc/data/value.expected delete mode 100644 test/xmlrpc/data/value.xml delete mode 100644 test/xmlrpc/data/xml1.expected delete mode 100644 test/xmlrpc/data/xml1.xml delete mode 100644 test/xmlrpc/htpasswd delete mode 100644 test/xmlrpc/test_client.rb delete mode 100644 test/xmlrpc/test_cookie.rb delete mode 100644 test/xmlrpc/test_datetime.rb delete mode 100644 test/xmlrpc/test_features.rb delete mode 100644 test/xmlrpc/test_marshal.rb delete mode 100644 test/xmlrpc/test_parser.rb delete mode 100644 test/xmlrpc/test_webrick_server.rb delete mode 100644 test/xmlrpc/webrick_testing.rb diff --git a/ChangeLog b/ChangeLog index a425abf795..786640f802 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +Mon May 16 11:39:02 2016 SHIBATA Hiroshi + + * lib/xmlrpc.rb, lib/xmlrpc/*, test/xmlrpc: XMLRPC is bundled gem + on Ruby 2.4. It is extracted to https://github.com/ruby/xmlrpc + [Feature #12160][ruby-core:74239] + * gems/bundled_gems: ditto. + Mon May 16 06:06:21 2016 Eric Wong * proc.c: fix RDoc of Proc#===/call/yield/[] diff --git a/gems/bundled_gems b/gems/bundled_gems index bb9b861c2e..99583c27c8 100644 --- a/gems/bundled_gems +++ b/gems/bundled_gems @@ -4,3 +4,4 @@ minitest 5.8.4 rake 11.1.2 net-telnet 0.1.1 did_you_mean 1.0.0 +xmlrpc 0.1.0 diff --git a/lib/xmlrpc.rb b/lib/xmlrpc.rb deleted file mode 100644 index 94d93a18b9..0000000000 --- a/lib/xmlrpc.rb +++ /dev/null @@ -1,291 +0,0 @@ -# frozen_string_literal: false -# == 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/ruby/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 Authentication -# * HTTPS protocol (SSL) -# -# * Parsers -# * REXML (XMLParser::REXMLStreamParser) -# * Not compiled (pure ruby) -# * See ruby standard library -# * libxml (LibXMLStreamParser) -# * Compiled -# * See https://rubygems.org/gems/libxml-ruby/ -# -# * General -# * possible to choose between XMLParser module (Expat wrapper) and REXML (pure Ruby) parsers -# * Marshalling Ruby objects to Hashes and reconstruct them later from a Hash -# * SandStorm component architecture XMLRPC::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}" -# -# === XMLRPC::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 -# -# === Using XMLRPC::Client::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 -# _proxy2_. 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 using XMLRPC::CGIServer -# -# 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 XMLRPC::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::Service::PublicInstanceMethodsInterface 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 XMLRPC::Server -# -# Same as CGI-based server, the only difference being -# -# 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 XMLParser or XMLWriter -# -# The examples above all use the default parser (which is now since 1.8 -# XMLParser::REXMLStreamParser) and a default XMLRPC::XMLWriter. -# If you want to use a different XMLParser, then you have to call the -# ParserWriterChooseMixin#set_parser method of XMLRPC::Client instances -# or instances of subclasses of XMLRPC::BasicServer or by editing -# xmlrpc/config.rb. -# -# XMLRPC::Client Example: -# -# # ... -# server = XMLRPC::Client.new( "xmlrpc-c.sourceforge.net", "/api/sample.php") -# server.set_parser(XMLRPC::XMLParser::XMLParser.new) -# # ... -# -# XMLRPC::Server Example: -# -# # ... -# s = XMLRPC::CGIServer.new -# s.set_parser(XMLRPC::XMLParser::XMLParser.new) -# # ... -# -# -# You can change the XML-writer by calling method ParserWriterChooseMixin#set_writer. -module XMLRPC; end diff --git a/lib/xmlrpc/base64.rb b/lib/xmlrpc/base64.rb deleted file mode 100644 index 21f8c65ce2..0000000000 --- a/lib/xmlrpc/base64.rb +++ /dev/null @@ -1,63 +0,0 @@ -# frozen_string_literal: false -# -# xmlrpc/base64.rb -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# Released under the same term of license as Ruby. - -module XMLRPC # :nodoc: - -# This class is necessary for 'xmlrpc4r' to determine that a string should -# be transmitted base64-encoded and not as a raw-string. -# -# You can use XMLRPC::Base64 on the client and server-side as a -# parameter and/or return-value. -class Base64 - - # Creates a new XMLRPC::Base64 instance with string +str+ as the - # internal string. When +state+ is +:dec+ it assumes that the - # string +str+ is not in base64 format (perhaps already decoded), - # otherwise if +state+ is +:enc+ it decodes +str+ - # and stores it as the internal string. - def initialize(str, state = :dec) - case state - when :enc - @str = Base64.decode(str) - when :dec - @str = str - else - raise ArgumentError, "wrong argument; either :enc or :dec" - end - end - - # Returns the decoded internal string. - def decoded - @str - end - - # Returns the base64 encoded internal string. - def encoded - Base64.encode(@str) - end - - - # Decodes string +str+ with base64 and returns that value. - def Base64.decode(str) - str.gsub(/\s+/, "").unpack("m")[0] - end - - # Encodes string +str+ with base64 and returns that value. - def Base64.encode(str) - [str].pack("m") - end - -end - - -end # module XMLRPC - - -=begin -= History - $Id$ -=end diff --git a/lib/xmlrpc/client.rb b/lib/xmlrpc/client.rb deleted file mode 100644 index 587a80bea3..0000000000 --- a/lib/xmlrpc/client.rb +++ /dev/null @@ -1,629 +0,0 @@ -# frozen_string_literal: false -# xmlrpc/client.rb -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# Released under the same term of license as Ruby. -# -# History -# $Id$ -# -require "xmlrpc/parser" -require "xmlrpc/create" -require "xmlrpc/config" -require "xmlrpc/utils" # ParserWriterChooseMixin -require "net/http" -require "uri" - -module XMLRPC # :nodoc: - - # Provides remote procedure calls to a XML-RPC server. - # - # After setting the connection-parameters with XMLRPC::Client.new which - # creates a new XMLRPC::Client instance, you can execute a remote procedure - # by sending the XMLRPC::Client#call or XMLRPC::Client#call2 - # message to this new instance. - # - # The given parameters indicate which method to call on the remote-side and - # of course the parameters for the remote procedure. - # - # require "xmlrpc/client" - # - # server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) - # begin - # param = server.call("michael.add", 4, 5) - # puts "4 + 5 = #{param}" - # rescue XMLRPC::FaultException => e - # puts "Error:" - # puts e.faultCode - # puts e.faultString - # end - # - # or - # - # require "xmlrpc/client" - # - # server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) - # ok, param = server.call2("michael.add", 4, 5) - # if ok then - # puts "4 + 5 = #{param}" - # else - # puts "Error:" - # puts param.faultCode - # puts param.faultString - # end - class Client - - USER_AGENT = "XMLRPC::Client (Ruby #{RUBY_VERSION})" - - include ParserWriterChooseMixin - include ParseContentType - - - # Creates an object which represents the remote XML-RPC server on the - # given +host+. If the server is CGI-based, +path+ is the - # path to the CGI-script, which will be called, otherwise (in the - # case of a standalone server) +path+ should be "/RPC2". - # +port+ is the port on which the XML-RPC server listens. - # - # If +proxy_host+ is given, then a proxy server listening at - # +proxy_host+ is used. +proxy_port+ is the port of the - # proxy server. - # - # Default values for +host+, +path+ and +port+ are 'localhost', '/RPC2' and - # '80' respectively using SSL '443'. - # - # If +user+ and +password+ are given, each time a request is sent, - # an Authorization header is sent. Currently only Basic Authentication is - # implemented, no Digest. - # - # If +use_ssl+ is set to +true+, communication over SSL is enabled. - # - # Parameter +timeout+ is the time to wait for a XML-RPC response, defaults to 30. - def initialize(host=nil, path=nil, port=nil, proxy_host=nil, proxy_port=nil, - user=nil, password=nil, use_ssl=nil, timeout=nil) - - @http_header_extra = nil - @http_last_response = nil - @cookie = nil - - @host = host || "localhost" - @path = path || "/RPC2" - @proxy_host = proxy_host - @proxy_port = proxy_port - @proxy_host ||= 'localhost' if @proxy_port != nil - @proxy_port ||= 8080 if @proxy_host != nil - @use_ssl = use_ssl || false - @timeout = timeout || 30 - - if use_ssl - require "net/https" - @port = port || 443 - else - @port = port || 80 - end - - @user, @password = user, password - - set_auth - - # convert ports to integers - @port = @port.to_i if @port != nil - @proxy_port = @proxy_port.to_i if @proxy_port != nil - - # HTTP object for synchronous calls - @http = net_http(@host, @port, @proxy_host, @proxy_port) - @http.use_ssl = @use_ssl if @use_ssl - @http.read_timeout = @timeout - @http.open_timeout = @timeout - - @parser = nil - @create = nil - end - - - class << self - - # Creates an object which represents the remote XML-RPC server at the - # given +uri+. The URI should have a host, port, path, user and password. - # Example: https://user:password@host:port/path - # - # Raises an ArgumentError if the +uri+ is invalid, - # or if the protocol isn't http or https. - # - # If a +proxy+ is given it should be in the form of "host:port". - # - # The optional +timeout+ defaults to 30 seconds. - def new2(uri, proxy=nil, timeout=nil) - begin - url = URI(uri) - rescue URI::InvalidURIError => e - raise ArgumentError, e.message, e.backtrace - end - - unless URI::HTTP === url - raise ArgumentError, "Wrong protocol specified. Only http or https allowed!" - end - - proto = url.scheme - user = url.user - passwd = url.password - host = url.host - port = url.port - path = url.path.empty? ? nil : url.request_uri - - proxy_host, proxy_port = (proxy || "").split(":") - proxy_port = proxy_port.to_i if proxy_port - - self.new(host, path, port, proxy_host, proxy_port, user, passwd, (proto == "https"), timeout) - end - - alias new_from_uri new2 - - # Receives a Hash and calls XMLRPC::Client.new - # with the corresponding values. - # - # The +hash+ parameter has following case-insensitive keys: - # * host - # * path - # * port - # * proxy_host - # * proxy_port - # * user - # * password - # * use_ssl - # * timeout - def new3(hash={}) - - # convert all keys into lowercase strings - h = {} - hash.each { |k,v| h[k.to_s.downcase] = v } - - self.new(h['host'], h['path'], h['port'], h['proxy_host'], h['proxy_port'], h['user'], h['password'], - h['use_ssl'], h['timeout']) - end - - alias new_from_hash new3 - - end - - - # Returns the Net::HTTP object for the client. If you want to - # change HTTP client options except header, cookie, timeout, - # user and password, use Net::HTTP directly. - # - # Since 2.1.0. - attr_reader :http - - # Add additional HTTP headers to the request - attr_accessor :http_header_extra - - # Returns the Net::HTTPResponse object of the last RPC. - attr_reader :http_last_response - - # Get and set the HTTP Cookie header. - attr_accessor :cookie - - - # Return the corresponding attributes. - attr_reader :timeout, :user, :password - - # Sets the Net::HTTP#read_timeout and Net::HTTP#open_timeout to - # +new_timeout+ - def timeout=(new_timeout) - @timeout = new_timeout - @http.read_timeout = @timeout - @http.open_timeout = @timeout - end - - # Changes the user for the Basic Authentication header to +new_user+ - def user=(new_user) - @user = new_user - set_auth - end - - # Changes the password for the Basic Authentication header to - # +new_password+ - def password=(new_password) - @password = new_password - set_auth - end - - # Invokes the method named +method+ with the parameters given by - # +args+ on the XML-RPC server. - # - # The +method+ parameter is converted into a String and should - # be a valid XML-RPC method-name. - # - # Each parameter of +args+ must be of one of the following types, - # where Hash, Struct and Array can contain any of these listed _types_: - # - # * Fixnum, Bignum - # * TrueClass, FalseClass, +true+, +false+ - # * String, Symbol - # * Float - # * Hash, Struct - # * Array - # * Date, Time, XMLRPC::DateTime - # * XMLRPC::Base64 - # * A Ruby object which class includes XMLRPC::Marshallable - # (only if Config::ENABLE_MARSHALLING is +true+). - # That object is converted into a hash, with one additional key/value - # pair ___class___ which contains the class name - # for restoring that object later. - # - # The method returns the return-value from the Remote Procedure Call. - # - # The type of the return-value is one of the types shown above. - # - # A Bignum is only allowed when it fits in 32-bit. A XML-RPC - # +dateTime.iso8601+ type is always returned as a XMLRPC::DateTime object. - # Struct is never returned, only a Hash, the same for a Symbol, where as a - # String is always returned. XMLRPC::Base64 is returned as a String from - # xmlrpc4r version 1.6.1 on. - # - # If the remote procedure returned a fault-structure, then a - # XMLRPC::FaultException exception is raised, which has two accessor-methods - # +faultCode+ an Integer, and +faultString+ a String. - def call(method, *args) - ok, param = call2(method, *args) - if ok - param - else - raise param - end - end - - # The difference between this method and XMLRPC::Client#call is, that - # this method will NOT raise a XMLRPC::FaultException exception. - # - # The method returns an array of two values. The first value indicates if - # the second value is +true+ or an XMLRPC::FaultException. - # - # Both are explained in XMLRPC::Client#call. - # - # Simple to remember: The "2" in "call2" denotes the number of values it returns. - def call2(method, *args) - request = create().methodCall(method, *args) - data = do_rpc(request, false) - parser().parseMethodResponse(data) - end - - # Similar to XMLRPC::Client#call, however can be called concurrently and - # use a new connection for each request. In contrast to the corresponding - # method without the +_async+ suffix, which use connect-alive (one - # connection for all requests). - # - # Note, that you have to use Thread to call these methods concurrently. - # The following example calls two methods concurrently: - # - # Thread.new { - # p client.call_async("michael.add", 4, 5) - # } - # - # Thread.new { - # p client.call_async("michael.div", 7, 9) - # } - # - def call_async(method, *args) - ok, param = call2_async(method, *args) - if ok - param - else - raise param - end - end - - # Same as XMLRPC::Client#call2, but can be called concurrently. - # - # See also XMLRPC::Client#call_async - def call2_async(method, *args) - request = create().methodCall(method, *args) - data = do_rpc(request, true) - parser().parseMethodResponse(data) - end - - - # You can use this method to execute several methods on a XMLRPC server - # which support the multi-call extension. - # - # s.multicall( - # ['michael.add', 3, 4], - # ['michael.sub', 4, 5] - # ) - # # => [7, -1] - def multicall(*methods) - ok, params = multicall2(*methods) - if ok - params - else - raise params - end - end - - # Same as XMLRPC::Client#multicall, but returns two parameters instead of - # raising an XMLRPC::FaultException. - # - # See XMLRPC::Client#call2 - def multicall2(*methods) - gen_multicall(methods, false) - end - - # Similar to XMLRPC::Client#multicall, however can be called concurrently and - # use a new connection for each request. In contrast to the corresponding - # method without the +_async+ suffix, which use connect-alive (one - # connection for all requests). - # - # Note, that you have to use Thread to call these methods concurrently. - # The following example calls two methods concurrently: - # - # Thread.new { - # p client.multicall_async("michael.add", 4, 5) - # } - # - # Thread.new { - # p client.multicall_async("michael.div", 7, 9) - # } - # - def multicall_async(*methods) - ok, params = multicall2_async(*methods) - if ok - params - else - raise params - end - end - - # Same as XMLRPC::Client#multicall2, but can be called concurrently. - # - # See also XMLRPC::Client#multicall_async - def multicall2_async(*methods) - gen_multicall(methods, true) - end - - - # Returns an object of class XMLRPC::Client::Proxy, initialized with - # +prefix+ and +args+. - # - # A proxy object returned by this method behaves like XMLRPC::Client#call, - # i.e. a call on that object will raise a XMLRPC::FaultException when a - # fault-structure is returned by that call. - def proxy(prefix=nil, *args) - Proxy.new(self, prefix, args, :call) - end - - # Almost the same like XMLRPC::Client#proxy only that a call on the returned - # XMLRPC::Client::Proxy object will return two parameters. - # - # See XMLRPC::Client#call2 - def proxy2(prefix=nil, *args) - Proxy.new(self, prefix, args, :call2) - end - - # Similar to XMLRPC::Client#proxy, however can be called concurrently and - # use a new connection for each request. In contrast to the corresponding - # method without the +_async+ suffix, which use connect-alive (one - # connection for all requests). - # - # Note, that you have to use Thread to call these methods concurrently. - # The following example calls two methods concurrently: - # - # Thread.new { - # p client.proxy_async("michael.add", 4, 5) - # } - # - # Thread.new { - # p client.proxy_async("michael.div", 7, 9) - # } - # - def proxy_async(prefix=nil, *args) - Proxy.new(self, prefix, args, :call_async) - end - - # Same as XMLRPC::Client#proxy2, but can be called concurrently. - # - # See also XMLRPC::Client#proxy_async - def proxy2_async(prefix=nil, *args) - Proxy.new(self, prefix, args, :call2_async) - end - - - private - - def net_http(host, port, proxy_host, proxy_port) - Net::HTTP.new host, port, proxy_host, proxy_port - end - - def dup_net_http - http = net_http(@http.address, - @http.port, - @http.proxy_address, - @http.proxy_port) - http.proxy_user = @http.proxy_user - http.proxy_pass = @http.proxy_pass - if @http.use_ssl? - http.use_ssl = true - Net::HTTP::SSL_ATTRIBUTES.each do |attribute| - http.__send__("#{attribute}=", @http.__send__(attribute)) - end - end - http.read_timeout = @http.read_timeout - http.open_timeout = @http.open_timeout - http - end - - def set_auth - if @user.nil? - @auth = nil - else - a = "#@user" - a << ":#@password" if @password != nil - @auth = "Basic " + [a].pack("m0") - end - end - - def do_rpc(request, async=false) - header = { - "User-Agent" => USER_AGENT, - "Content-Type" => "text/xml; charset=utf-8", - "Content-Length" => request.bytesize.to_s, - "Connection" => (async ? "close" : "keep-alive") - } - - header["Cookie"] = @cookie if @cookie - header.update(@http_header_extra) if @http_header_extra - - if @auth != nil - # add authorization header - header["Authorization"] = @auth - end - - resp = nil - @http_last_response = nil - - if async - # use a new HTTP object for each call - http = dup_net_http - - # post request - http.start { - resp = http.request_post(@path, request, header) - } - else - # reuse the HTTP object for each call => connection alive is possible - # we must start connection explicitly first time so that http.request - # does not assume that we don't want keepalive - @http.start if not @http.started? - - # post request - resp = @http.request_post(@path, request, header) - end - - @http_last_response = resp - - data = resp.body - - if resp.code == "401" - # Authorization Required - raise "Authorization failed.\nHTTP-Error: #{resp.code} #{resp.message}" - elsif resp.code[0,1] != "2" - raise "HTTP-Error: #{resp.code} #{resp.message}" - end - - # assume text/xml on instances where Content-Type header is not set - ct_expected = resp["Content-Type"] || 'text/xml' - ct = parse_content_type(ct_expected).first - if ct != "text/xml" - if ct == "text/html" - raise "Wrong content-type (received '#{ct}' but expected 'text/xml'): \n#{data}" - else - raise "Wrong content-type (received '#{ct}' but expected 'text/xml')" - end - end - - expected = resp["Content-Length"] || "" - if data.nil? or data.bytesize == 0 - raise "Wrong size. Was #{data.bytesize}, should be #{expected}" - end - - parse_set_cookies(resp.get_fields("Set-Cookie")) - - return data - end - - def parse_set_cookies(set_cookies) - return if set_cookies.nil? - return if set_cookies.empty? - require 'webrick/cookie' - pairs = {} - set_cookies.each do |set_cookie| - cookie = WEBrick::Cookie.parse_set_cookie(set_cookie) - pairs.delete(cookie.name) - pairs[cookie.name] = cookie.value - end - cookies = pairs.collect do |name, value| - WEBrick::Cookie.new(name, value).to_s - end - @cookie = cookies.join("; ") - end - - def gen_multicall(methods=[], async=false) - meth = :call2 - meth = :call2_async if async - - ok, params = self.send(meth, "system.multicall", - methods.collect {|m| {'methodName' => m[0], 'params' => m[1..-1]} } - ) - - if ok - params = params.collect do |param| - if param.is_a? Array - param[0] - elsif param.is_a? Hash - XMLRPC::FaultException.new(param["faultCode"], param["faultString"]) - else - raise "Wrong multicall return value" - end - end - end - - return ok, params - end - - - - # XML-RPC calls look nicer! - # - # You can call any method onto objects of that class - the object handles - # XMLRPC::Client::Proxy#method_missing and will forward the method call to - # a XML-RPC server. - # - # Don't use this class directly, instead use the public instance method - # XMLRPC::Client#proxy or XMLRPC::Client#proxy2. - # - # require "xmlrpc/client" - # - # server = XMLRPC::Client.new("www.ruby-lang.org", "/RPC2", 80) - # - # michael = server.proxy("michael") - # michael2 = server.proxy("michael", 4) - # - # # both calls should return the same value '9'. - # p michael.add(4,5) - # p michael2.add(5) - class Proxy - - # Creates an object which provides XMLRPC::Client::Proxy#method_missing. - # - # The given +server+ must be an instance of XMLRPC::Client, which is the - # XML-RPC server to be used for a XML-RPC call. - # - # +prefix+ and +delim+ will be prepended to the method name called onto this object. - # - # An optional parameter +meth+ is the method to use for a RPC. - # It can be either, call, call2, call_async, call2_async - # - # +args+ are arguments which are automatically given to every XML-RPC - # call before being provided through +method_missing+. - def initialize(server, prefix, args=[], meth=:call, delim=".") - @server = server - @prefix = prefix ? prefix + delim : "" - @args = args - @meth = meth - end - - # Every method call is forwarded to the XML-RPC server defined in - # XMLRPC::Client::Proxy#new. - # - # Note: Inherited methods from class Object cannot be used as XML-RPC - # names, because they get around +method_missing+. - def method_missing(mid, *args) - pre = @prefix + mid.to_s - arg = @args + args - @server.send(@meth, pre, *arg) - end - - end # class Proxy - - end # class Client - -end # module XMLRPC diff --git a/lib/xmlrpc/config.rb b/lib/xmlrpc/config.rb deleted file mode 100644 index b7ed7a9f71..0000000000 --- a/lib/xmlrpc/config.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: false -# -# $Id$ -# Configuration file for XML-RPC for Ruby -# - -module XMLRPC # :nodoc: - - module Config - - # or XMLWriter::XMLParser - DEFAULT_WRITER = XMLWriter::Simple - - # === Available parsers - # - # * XMLParser::REXMLStreamParser - # * XMLParser::LibXMLStreamParser - DEFAULT_PARSER = XMLParser::REXMLStreamParser - - # enable tag - ENABLE_NIL_CREATE = false - ENABLE_NIL_PARSER = false - - # allows integers greater than 32-bit if +true+ - ENABLE_BIGINT = false - - # enable marshalling Ruby objects which include XMLRPC::Marshallable - ENABLE_MARSHALLING = true - - # enable multiCall extension by default - ENABLE_MULTICALL = false - - # enable Introspection extension by default - ENABLE_INTROSPECTION = false - - end - -end - diff --git a/lib/xmlrpc/create.rb b/lib/xmlrpc/create.rb deleted file mode 100644 index 93822c4dd2..0000000000 --- a/lib/xmlrpc/create.rb +++ /dev/null @@ -1,287 +0,0 @@ -# frozen_string_literal: false -# -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# $Id$ -# - -require "date" -require "xmlrpc/base64" - -module XMLRPC # :nodoc: - - module XMLWriter - - class Abstract - def ele(name, *children) - element(name, nil, *children) - end - - def tag(name, txt) - element(name, nil, text(txt)) - end - end - - - class Simple < Abstract - - def document_to_str(doc) - doc - end - - def document(*params) - params.join("") - end - - def pi(name, *params) - "" - end - - def element(name, attrs, *children) - raise "attributes not yet implemented" unless attrs.nil? - if children.empty? - "<#{name}/>" - else - "<#{name}>" + children.join("") + "" - end - end - - def text(txt) - cleaned = txt.dup - cleaned.gsub!(/&/, '&') - cleaned.gsub!(//, '>') - cleaned - end - - end # class Simple - - - class XMLParser < Abstract - - def initialize - require "xmltreebuilder" - end - - def document_to_str(doc) - doc.to_s - end - - def document(*params) - XML::SimpleTree::Document.new(*params) - end - - def pi(name, *params) - XML::SimpleTree::ProcessingInstruction.new(name, *params) - end - - def element(name, attrs, *children) - XML::SimpleTree::Element.new(name, attrs, *children) - end - - def text(txt) - XML::SimpleTree::Text.new(txt) - end - - end # class XMLParser - - Classes = [Simple, XMLParser] - - # yields an instance of each installed XML writer - def self.each_installed_writer - XMLRPC::XMLWriter::Classes.each do |klass| - begin - yield klass.new - rescue LoadError - end - end - end - - end # module XMLWriter - - # Creates XML-RPC call/response documents - # - class Create - - def initialize(xml_writer = nil) - @writer = xml_writer || Config::DEFAULT_WRITER.new - end - - - def methodCall(name, *params) - name = name.to_s - - if name !~ /[a-zA-Z0-9_.:\/]+/ - raise ArgumentError, "Wrong XML-RPC method-name" - end - - parameter = params.collect do |param| - @writer.ele("param", conv2value(param)) - end - - tree = @writer.document( - @writer.pi("xml", 'version="1.0"'), - @writer.ele("methodCall", - @writer.tag("methodName", name), - @writer.ele("params", *parameter) - ) - ) - - @writer.document_to_str(tree) + "\n" - end - - - - # - # Generates a XML-RPC methodResponse document - # - # When +is_ret+ is +false+ then the +params+ array must - # contain only one element, which is a structure - # of a fault return-value. - # - # When +is_ret+ is +true+ then a normal - # return-value of all the given +params+ is created. - # - def methodResponse(is_ret, *params) - - if is_ret - resp = params.collect do |param| - @writer.ele("param", conv2value(param)) - end - - resp = [@writer.ele("params", *resp)] - else - if params.size != 1 or params[0] === XMLRPC::FaultException - raise ArgumentError, "no valid fault-structure given" - end - resp = @writer.ele("fault", conv2value(params[0].to_h)) - end - - - tree = @writer.document( - @writer.pi("xml", 'version="1.0"'), - @writer.ele("methodResponse", resp) - ) - - @writer.document_to_str(tree) + "\n" - end - - - - private - - # - # Converts a Ruby object into a XML-RPC tag - # - def conv2value(param) # :doc: - - val = case param - when Fixnum, Bignum - # XML-RPC's int is 32bit int, and Fixnum also may be beyond 32bit - if Config::ENABLE_BIGINT - @writer.tag("i4", param.to_s) - else - if param >= -(2**31) and param <= (2**31-1) - @writer.tag("i4", param.to_s) - else - raise "Bignum is too big! Must be signed 32-bit integer!" - end - end - when TrueClass, FalseClass - @writer.tag("boolean", param ? "1" : "0") - - when Symbol - @writer.tag("string", param.to_s) - - when String - @writer.tag("string", param) - - when NilClass - if Config::ENABLE_NIL_CREATE - @writer.ele("nil") - else - raise "Wrong type NilClass. Not allowed!" - end - - when Float - raise "Wrong value #{param}. Not allowed!" unless param.finite? - @writer.tag("double", param.to_s) - - when Struct - h = param.members.collect do |key| - value = param[key] - @writer.ele("member", - @writer.tag("name", key.to_s), - conv2value(value) - ) - end - - @writer.ele("struct", *h) - - when Hash - # TODO: can a Hash be empty? - - h = param.collect do |key, value| - @writer.ele("member", - @writer.tag("name", key.to_s), - conv2value(value) - ) - end - - @writer.ele("struct", *h) - - when Array - # TODO: can an Array be empty? - a = param.collect {|v| conv2value(v) } - - @writer.ele("array", - @writer.ele("data", *a) - ) - - when Time, Date, ::DateTime - @writer.tag("dateTime.iso8601", param.strftime("%Y%m%dT%H:%M:%S")) - - when XMLRPC::DateTime - @writer.tag("dateTime.iso8601", - format("%.4d%02d%02dT%02d:%02d:%02d", *param.to_a)) - - when XMLRPC::Base64 - @writer.tag("base64", param.encoded) - - else - if Config::ENABLE_MARSHALLING and param.class.included_modules.include? XMLRPC::Marshallable - # convert Ruby object into Hash - ret = {"___class___" => param.class.name} - param.instance_variables.each {|v| - name = v[1..-1] - val = param.instance_variable_get(v) - - if val.nil? - ret[name] = val if Config::ENABLE_NIL_CREATE - else - ret[name] = val - end - } - return conv2value(ret) - else - ok, pa = wrong_type(param) - if ok - return conv2value(pa) - else - raise "Wrong type!" - end - end - end - - @writer.ele("value", val) - end - - def wrong_type(value) - false - end - - - end # class Create - -end # module XMLRPC - diff --git a/lib/xmlrpc/datetime.rb b/lib/xmlrpc/datetime.rb deleted file mode 100644 index 431ac24aa9..0000000000 --- a/lib/xmlrpc/datetime.rb +++ /dev/null @@ -1,130 +0,0 @@ -# frozen_string_literal: false -# -# xmlrpc/datetime.rb -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# Released under the same term of license as Ruby. -# -require "date" - -module XMLRPC # :nodoc: - -# This class is important to handle XMLRPC +dateTime.iso8601+ values, -# correctly, because normal UNIX-dates, ie: Date, only handle dates -# from year 1970 on, and ruby's native Time class handles dates without the -# time component. -# -# XMLRPC::DateTime is able to store a XMLRPC +dateTime.iso8601+ value correctly. -class DateTime - - # Return the value of the specified date/time component. - attr_reader :year, :month, :day, :hour, :min, :sec - - # Set +value+ as the new date/time component. - # - # Raises ArgumentError if the given +value+ is out of range, or in the case - # of XMLRPC::DateTime#year= if +value+ is not of type Integer. - def year= (value) - raise ArgumentError, "date/time out of range" unless value.is_a? Integer - @year = value - end - - # Set +value+ as the new date/time component. - # - # Raises an ArgumentError if the given +value+ isn't between 1 and 12. - def month= (value) - raise ArgumentError, "date/time out of range" unless (1..12).include? value - @month = value - end - - # Set +value+ as the new date/time component. - # - # Raises an ArgumentError if the given +value+ isn't between 1 and 31. - def day= (value) - raise ArgumentError, "date/time out of range" unless (1..31).include? value - @day = value - end - - # Set +value+ as the new date/time component. - # - # Raises an ArgumentError if the given +value+ isn't between 0 and 24. - def hour= (value) - raise ArgumentError, "date/time out of range" unless (0..24).include? value - @hour = value - end - - # Set +value+ as the new date/time component. - # - # Raises an ArgumentError if the given +value+ isn't between 0 and 59. - def min= (value) - raise ArgumentError, "date/time out of range" unless (0..59).include? value - @min = value - end - - # Set +value+ as the new date/time component. - # - # Raises an ArgumentError if the given +value+ isn't between 0 and 59. - def sec= (value) - raise ArgumentError, "date/time out of range" unless (0..59).include? value - @sec = value - end - - # Alias for XMLRPC::DateTime#month. - alias mon month - # Alias for XMLRPC::DateTime#month=. - alias mon= month= - - - # Creates a new XMLRPC::DateTime instance with the - # parameters +year+, +month+, +day+ as date and - # +hour+, +min+, +sec+ as time. - # - # Raises an ArgumentError if a parameter is out of range, - # or if +year+ is not of the Integer type. - def initialize(year, month, day, hour, min, sec) - self.year, self.month, self.day = year, month, day - self.hour, self.min, self.sec = hour, min, sec - end - - # Return a Time object of the date/time which represents +self+. - # If the @year is below 1970, this method returns +nil+, - # because Time cannot handle years below 1970. - # - # The timezone used is GMT. - def to_time - if @year >= 1970 - Time.gm(*to_a) - else - nil - end - end - - # Return a Date object of the date which represents +self+. - # - # The Date object do _not_ contain the time component (only date). - def to_date - Date.new(*to_a[0,3]) - end - - # Returns all date/time components in an array. - # - # Returns +[year, month, day, hour, min, sec]+. - def to_a - [@year, @month, @day, @hour, @min, @sec] - end - - # Returns whether or not all date/time components are an array. - def ==(o) - self.to_a == Array(o) rescue false - end - -end - - -end # module XMLRPC - - -=begin -= History - $Id$ -=end diff --git a/lib/xmlrpc/marshal.rb b/lib/xmlrpc/marshal.rb deleted file mode 100644 index 42b7b1e125..0000000000 --- a/lib/xmlrpc/marshal.rb +++ /dev/null @@ -1,67 +0,0 @@ -# frozen_string_literal: false -# -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# $Id$ -# - -require "xmlrpc/parser" -require "xmlrpc/create" -require "xmlrpc/config" -require "xmlrpc/utils" - -module XMLRPC # :nodoc: - - # Marshalling of XMLRPC::Create#methodCall and XMLRPC::Create#methodResponse - class Marshal - include ParserWriterChooseMixin - - class << self - - def dump_call( methodName, *params ) - new.dump_call( methodName, *params ) - end - - def dump_response( param ) - new.dump_response( param ) - end - - def load_call( stringOrReadable ) - new.load_call( stringOrReadable ) - end - - def load_response( stringOrReadable ) - new.load_response( stringOrReadable ) - end - - alias dump dump_response - alias load load_response - - end # class self - - def initialize( parser = nil, writer = nil ) - set_parser( parser ) - set_writer( writer ) - end - - def dump_call( methodName, *params ) - create.methodCall( methodName, *params ) - end - - def dump_response( param ) - create.methodResponse( ! param.kind_of?( XMLRPC::FaultException ) , param ) - end - - # Returns [ methodname, params ] - def load_call( stringOrReadable ) - parser.parseMethodCall( stringOrReadable ) - end - - # Returns +paramOrFault+ - def load_response( stringOrReadable ) - parser.parseMethodResponse( stringOrReadable )[1] - end - - end # class Marshal - -end diff --git a/lib/xmlrpc/parser.rb b/lib/xmlrpc/parser.rb deleted file mode 100644 index a58da33720..0000000000 --- a/lib/xmlrpc/parser.rb +++ /dev/null @@ -1,642 +0,0 @@ -# frozen_string_literal: false -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# $Id$ -# - - -require "date" -require "xmlrpc/base64" -require "xmlrpc/datetime" - - -module XMLRPC # :nodoc: - - # Raised when the remote procedure returns a fault-structure, which has two - # accessor-methods +faultCode+ an Integer, and +faultString+ a String. - class FaultException < StandardError - attr_reader :faultCode, :faultString - - # Creates a new XMLRPC::FaultException instance. - # - # +faultString+ is passed to StandardError as the +msg+ of the Exception. - def initialize(faultCode, faultString) - @faultCode = faultCode - @faultString = faultString - super(@faultString) - end - - # The +faultCode+ and +faultString+ of the exception in a Hash. - def to_h - {"faultCode" => @faultCode, "faultString" => @faultString} - end - end - - # Helper class used to convert types. - module Convert - - # Converts a String to an Integer - # - # See also String.to_i - def self.int(str) - str.to_i - end - - # Converts a String to +true+ or +false+ - # - # Raises an exception if +str+ is not +0+ or +1+ - def self.boolean(str) - case str - when "0" then false - when "1" then true - else - raise "RPC-value of type boolean is wrong" - end - end - - # Converts a String to a Float - # - # See also String.to_f - def self.double(str) - str.to_f - end - - # Converts a the given +str+ to a +dateTime.iso8601+ formatted date. - # - # Raises an exception if the String isn't in +dateTime.iso8601+ format. - # - # See also, XMLRPC::DateTime - def self.dateTime(str) - case str - when /^(-?\d\d\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(?:Z|([+-])(\d\d):?(\d\d))?$/ - a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i} - if $7 - ofs = $8.to_i*3600 + $9.to_i*60 - ofs = -ofs if $7=='+' - utc = Time.utc(*a) + ofs - a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ] - end - XMLRPC::DateTime.new(*a) - when /^(-?\d\d)-?(\d\d)-?(\d\d)T(\d\d):(\d\d):(\d\d)(Z|([+-]\d\d):(\d\d))?$/ - a = [$1, $2, $3, $4, $5, $6].collect{|i| i.to_i} - if a[0] < 70 - a[0] += 2000 - else - a[0] += 1900 - end - if $7 - ofs = $8.to_i*3600 + $9.to_i*60 - ofs = -ofs if $7=='+' - utc = Time.utc(*a) + ofs - a = [ utc.year, utc.month, utc.day, utc.hour, utc.min, utc.sec ] - end - XMLRPC::DateTime.new(*a) - else - raise "wrong dateTime.iso8601 format " + str - end - end - - # Decodes the given +str+ using XMLRPC::Base64.decode - def self.base64(str) - XMLRPC::Base64.decode(str) - end - - # Converts the given +hash+ to a marshalled object. - # - # Returns the given +hash+ if an exception occurs. - def self.struct(hash) - # convert to marshalled object - klass = hash["___class___"] - if klass.nil? or Config::ENABLE_MARSHALLING == false - hash - else - begin - mod = Module - klass.split("::").each {|const| mod = mod.const_get(const.strip)} - - obj = mod.allocate - - hash.delete "___class___" - hash.each {|key, value| - obj.instance_variable_set("@#{ key }", value) if key =~ /^([a-zA-Z_]\w*)$/ - } - obj - rescue - hash - end - end - end - - # Converts the given +hash+ to an XMLRPC::FaultException object by passing - # the +faultCode+ and +faultString+ attributes of the Hash to - # XMLRPC::FaultException.new - # - # Raises an Exception if the given +hash+ doesn't meet the requirements. - # Those requirements being: - # * 2 keys - # * 'faultCode' key is an Integer - # * 'faultString' key is a String - def self.fault(hash) - if hash.kind_of? Hash and hash.size == 2 and - hash.has_key? "faultCode" and hash.has_key? "faultString" and - hash["faultCode"].kind_of? Integer and hash["faultString"].kind_of? String - - XMLRPC::FaultException.new(hash["faultCode"], hash["faultString"]) - else - raise "wrong fault-structure: #{hash.inspect}" - end - end - - end # module Convert - - # Parser for XML-RPC call and response - module XMLParser - - class AbstractTreeParser - - def parseMethodResponse(str) - methodResponse_document(createCleanedTree(str)) - end - - def parseMethodCall(str) - methodCall_document(createCleanedTree(str)) - end - - private - - # Removes all whitespaces but in the tags i4, i8, int, boolean.... - # and all comments - def removeWhitespacesAndComments(node) - remove = [] - childs = node.childNodes.to_a - childs.each do |nd| - case _nodeType(nd) - when :TEXT - # TODO: add nil? - unless %w(i4 i8 int boolean string double dateTime.iso8601 base64).include? node.nodeName - - if node.nodeName == "value" - if not node.childNodes.to_a.detect {|n| _nodeType(n) == :ELEMENT}.nil? - remove << nd if nd.nodeValue.strip == "" - end - else - remove << nd if nd.nodeValue.strip == "" - end - end - when :COMMENT - remove << nd - else - removeWhitespacesAndComments(nd) - end - end - - remove.each { |i| node.removeChild(i) } - end - - - def nodeMustBe(node, name) - cmp = case name - when Array - name.include?(node.nodeName) - when String - name == node.nodeName - else - raise "error" - end - - if not cmp then - raise "wrong xml-rpc (name)" - end - - node - end - - # Returns, when successfully the only child-node - def hasOnlyOneChild(node, name=nil) - if node.childNodes.to_a.size != 1 - raise "wrong xml-rpc (size)" - end - if name != nil then - nodeMustBe(node.firstChild, name) - end - end - - - def assert(b) - if not b then - raise "assert-fail" - end - end - - # The node `node` has empty string or string - def text_zero_one(node) - nodes = node.childNodes.to_a.size - - if nodes == 1 - text(node.firstChild) - elsif nodes == 0 - "" - else - raise "wrong xml-rpc (size)" - end - end - - - def integer(node) - #TODO: check string for float because to_i returnsa - # 0 when wrong string - nodeMustBe(node, %w(i4 i8 int)) - hasOnlyOneChild(node) - - Convert.int(text(node.firstChild)) - end - - def boolean(node) - nodeMustBe(node, "boolean") - hasOnlyOneChild(node) - - Convert.boolean(text(node.firstChild)) - end - - def v_nil(node) - nodeMustBe(node, "nil") - assert( node.childNodes.to_a.size == 0 ) - nil - end - - def string(node) - nodeMustBe(node, "string") - text_zero_one(node) - end - - def double(node) - #TODO: check string for float because to_f returnsa - # 0.0 when wrong string - nodeMustBe(node, "double") - hasOnlyOneChild(node) - - Convert.double(text(node.firstChild)) - end - - def dateTime(node) - nodeMustBe(node, "dateTime.iso8601") - hasOnlyOneChild(node) - - Convert.dateTime( text(node.firstChild) ) - end - - def base64(node) - nodeMustBe(node, "base64") - #hasOnlyOneChild(node) - - Convert.base64(text_zero_one(node)) - end - - def member(node) - nodeMustBe(node, "member") - assert( node.childNodes.to_a.size == 2 ) - - [ name(node[0]), value(node[1]) ] - end - - def name(node) - nodeMustBe(node, "name") - #hasOnlyOneChild(node) - text_zero_one(node) - end - - def array(node) - nodeMustBe(node, "array") - hasOnlyOneChild(node, "data") - data(node.firstChild) - end - - def data(node) - nodeMustBe(node, "data") - - node.childNodes.to_a.collect do |val| - value(val) - end - end - - def param(node) - nodeMustBe(node, "param") - hasOnlyOneChild(node, "value") - value(node.firstChild) - end - - def methodResponse(node) - nodeMustBe(node, "methodResponse") - hasOnlyOneChild(node, %w(params fault)) - child = node.firstChild - - case child.nodeName - when "params" - [ true, params(child,false) ] - when "fault" - [ false, fault(child) ] - else - raise "unexpected error" - end - - end - - def methodName(node) - nodeMustBe(node, "methodName") - hasOnlyOneChild(node) - text(node.firstChild) - end - - def params(node, call=true) - nodeMustBe(node, "params") - - if call - node.childNodes.to_a.collect do |n| - param(n) - end - else # response (only one param) - hasOnlyOneChild(node) - param(node.firstChild) - end - end - - def fault(node) - nodeMustBe(node, "fault") - hasOnlyOneChild(node, "value") - f = value(node.firstChild) - Convert.fault(f) - end - - - - # _nodeType is defined in the subclass - def text(node) - assert( _nodeType(node) == :TEXT ) - assert( node.hasChildNodes == false ) - assert( node.nodeValue != nil ) - - node.nodeValue.to_s - end - - def struct(node) - nodeMustBe(node, "struct") - - hash = {} - node.childNodes.to_a.each do |me| - n, v = member(me) - hash[n] = v - end - - Convert.struct(hash) - end - - - def value(node) - nodeMustBe(node, "value") - nodes = node.childNodes.to_a.size - if nodes == 0 - return "" - elsif nodes > 1 - raise "wrong xml-rpc (size)" - end - - child = node.firstChild - - case _nodeType(child) - when :TEXT - text_zero_one(node) - when :ELEMENT - case child.nodeName - when "i4", "i8", "int" then integer(child) - when "boolean" then boolean(child) - when "string" then string(child) - when "double" then double(child) - when "dateTime.iso8601" then dateTime(child) - when "base64" then base64(child) - when "struct" then struct(child) - when "array" then array(child) - when "nil" - if Config::ENABLE_NIL_PARSER - v_nil(child) - else - raise "wrong/unknown XML-RPC type 'nil'" - end - else - raise "wrong/unknown XML-RPC type" - end - else - raise "wrong type of node" - end - - end - - def methodCall(node) - nodeMustBe(node, "methodCall") - assert( (1..2).include?( node.childNodes.to_a.size ) ) - name = methodName(node[0]) - - if node.childNodes.to_a.size == 2 then - pa = params(node[1]) - else # no parameters given - pa = [] - end - [name, pa] - end - - end # module TreeParserMixin - - class AbstractStreamParser - def parseMethodResponse(str) - parser = @parser_class.new - parser.parse(str) - raise "No valid method response!" if parser.method_name != nil - if parser.fault != nil - # is a fault structure - [false, parser.fault] - else - # is a normal return value - raise "Missing return value!" if parser.params.size == 0 - raise "Too many return values. Only one allowed!" if parser.params.size > 1 - [true, parser.params[0]] - end - end - - def parseMethodCall(str) - parser = @parser_class.new - parser.parse(str) - raise "No valid method call - missing method name!" if parser.method_name.nil? - [parser.method_name, parser.params] - end - end - - module StreamParserMixin - attr_reader :params - attr_reader :method_name - attr_reader :fault - - def initialize(*a) - super(*a) - @params = [] - @values = [] - @val_stack = [] - - @names = [] - @name = [] - - @structs = [] - @struct = {} - - @method_name = nil - @fault = nil - - @data = nil - end - - def startElement(name, attrs=[]) - @data = nil - case name - when "value" - @value = nil - when "nil" - raise "wrong/unknown XML-RPC type 'nil'" unless Config::ENABLE_NIL_PARSER - @value = :nil - when "array" - @val_stack << @values - @values = [] - when "struct" - @names << @name - @name = [] - - @structs << @struct - @struct = {} - end - end - - def endElement(name) - @data ||= "" - case name - when "string" - @value = @data - when "i4", "i8", "int" - @value = Convert.int(@data) - when "boolean" - @value = Convert.boolean(@data) - when "double" - @value = Convert.double(@data) - when "dateTime.iso8601" - @value = Convert.dateTime(@data) - when "base64" - @value = Convert.base64(@data) - when "value" - @value = @data if @value.nil? - @values << (@value == :nil ? nil : @value) - when "array" - @value = @values - @values = @val_stack.pop - when "struct" - @value = Convert.struct(@struct) - - @name = @names.pop - @struct = @structs.pop - when "name" - @name[0] = @data - when "member" - @struct[@name[0]] = @values.pop - - when "param" - @params << @values[0] - @values = [] - - when "fault" - @fault = Convert.fault(@values[0]) - - when "methodName" - @method_name = @data - end - - @data = nil - end - - def character(data) - if @data - @data << data - else - @data = data - end - end - - end # module StreamParserMixin - - class REXMLStreamParser < AbstractStreamParser - def initialize - require "rexml/document" - @parser_class = StreamListener - end - - class StreamListener - include StreamParserMixin - - alias :tag_start :startElement - alias :tag_end :endElement - alias :text :character - alias :cdata :character - - def method_missing(*a) - # ignore - end - - def parse(str) - REXML::Document.parse_stream(str, self) - end - end - - end - - class LibXMLStreamParser < AbstractStreamParser - def initialize - require 'libxml' - @parser_class = LibXMLStreamListener - end - - class LibXMLStreamListener - include StreamParserMixin - - def on_start_element_ns(name, attributes, prefix, uri, namespaces) - startElement(name) - end - - def on_end_element_ns(name, prefix, uri) - endElement(name) - end - - alias :on_characters :character - alias :on_cdata_block :character - - def method_missing(*a) - end - - def parse(str) - parser = LibXML::XML::SaxParser.string(str) - parser.callbacks = self - parser.parse() - end - end - end - - Classes = [REXMLStreamParser, LibXMLStreamParser] - - # yields an instance of each installed parser - def self.each_installed_parser - XMLRPC::XMLParser::Classes.each do |klass| - begin - yield klass.new - rescue LoadError - end - end - end - - end # module XMLParser - - -end # module XMLRPC - diff --git a/lib/xmlrpc/server.rb b/lib/xmlrpc/server.rb deleted file mode 100644 index cd0fdbad38..0000000000 --- a/lib/xmlrpc/server.rb +++ /dev/null @@ -1,708 +0,0 @@ -# frozen_string_literal: false -# xmlrpc/server.rb -# Copyright (C) 2001, 2002, 2003, 2005 by Michael Neumann (mneumann@ntecs.de) -# -# Released under the same term of license as Ruby. - -require "xmlrpc/parser" -require "xmlrpc/create" -require "xmlrpc/config" -require "xmlrpc/utils" # ParserWriterChooseMixin - - - -module XMLRPC # :nodoc: - - -# This is the base class for all XML-RPC server-types (CGI, standalone). -# 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, or 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. -class BasicServer - - include ParserWriterChooseMixin - include ParseContentType - - ERR_METHOD_MISSING = 1 - ERR_UNCAUGHT_EXCEPTION = 2 - ERR_MC_WRONG_PARAM = 3 - ERR_MC_MISSING_PARAMS = 4 - ERR_MC_MISSING_METHNAME = 5 - ERR_MC_RECURSIVE_CALL = 6 - ERR_MC_WRONG_PARAM_PARAMS = 7 - ERR_MC_EXPECTED_STRUCT = 8 - - - # 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 initialize method. - # - # The parameter +class_delim+ is used by add_handler, see - # XMLRPC::BasicServer#add_handler, when an object is added as a handler, to - # delimit the object-prefix and the method-name. - def initialize(class_delim=".") - @handler = [] - @default_handler = nil - @service_hook = nil - - @class_delim = class_delim - @create = nil - @parser = nil - - add_multicall if Config::ENABLE_MULTICALL - add_introspection if Config::ENABLE_INTROSPECTION - end - - # 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 signatures. - # - # Value type-names are "int, boolean, double, string, dateTime.iso8601, - # base64, array, struct". - # - # Parameter +help+ is a String with information about how to call this method etc. - # - # When a method fails, it can tell 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 - # end - # end - # - # In the case of b==0 the client gets an object back of type - # XMLRPC::FaultException that has a +faultCode+ and +faultString+ field. - # - # This is the second form of (()). - # 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 XMLRPC::BasicServer.new plays it's role, a - # XML-RPC method-name is defined by +prefix+ + +class_delim+ + "name - # of method". - # - # The third form of +add_handler is to use XMLRPC::Service::Interface to - # generate an object, which represents an interface (with signature and - # help text) for a handler class. - # - # The +interface+ parameter must be an instance of XMLRPC::Service::Interface. - # Adds all methods of +obj+ which are defined in the +interface+ to the server. - # - # This is the recommended way of adding services to a server! - def add_handler(prefix, obj_or_signature=nil, help=nil, &block) - if block_given? - # proc-handler - @handler << [prefix, block, obj_or_signature, help] - else - if prefix.kind_of? String - # class-handler - raise ArgumentError, "Expected non-nil value" if obj_or_signature.nil? - @handler << [prefix + @class_delim, obj_or_signature] - elsif prefix.kind_of? XMLRPC::Service::BasicInterface - # class-handler with interface - # add all methods - @handler += prefix.get_methods(obj_or_signature, @class_delim) - else - raise ArgumentError, "Wrong type for parameter 'prefix'" - end - end - self - end - - # Returns the service-hook, which is called on each service request (RPC) - # unless it's +nil+. - def get_service_hook - @service_hook - end - - # 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 the +handler+ parameter. - # - # The service-hook is called with a Proc object along with any parameters. - # - # An example: - # - # server.set_service_hook {|obj, *args| - # begin - # ret = obj.call(*args) # call the original service-method - # # could convert the return value - # rescue - # # rescue exceptions - # end - # } - # - def set_service_hook(&handler) - @service_hook = handler - self - end - - # Returns the default-handler, which is called when no handler for - # a method-name is found. - # - # It is either a Proc object or +nil+. - def get_default_handler - @default_handler - end - - # 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". - def set_default_handler(&handler) - @default_handler = handler - self - end - - # Adds the multi-call handler "system.multicall". - def add_multicall - add_handler("system.multicall", %w(array array), "Multicall Extension") do |arrStructs| - 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"] - - if params.nil? - multicall_fault(ERR_MC_MISSING_PARAMS, "Missing params") - elsif methodName.nil? - multicall_fault(ERR_MC_MISSING_METHNAME, "Missing methodName") - else - if methodName == "system.multicall" - multicall_fault(ERR_MC_RECURSIVE_CALL, "Recursive system.multicall forbidden") - else - unless params.is_a? Array - multicall_fault(ERR_MC_WRONG_PARAM_PARAMS, "Parameter params have to be an Array") - else - ok, val = call_method(methodName, *params) - if ok - # correct return value - [val] - else - # exception - multicall_fault(val.faultCode, val.faultString) - end - end - end - end - - else - multicall_fault(ERR_MC_EXPECTED_STRUCT, "system.multicall expected struct") - end - } - end # end add_handler - self - end - - # Adds the introspection handlers "system.listMethods", - # "system.methodSignature" and - # "system.methodHelp", where only the first one works. - def add_introspection - add_handler("system.listMethods",%w(array), "List methods available on this XML-RPC server") do - methods = [] - @handler.each do |name, obj| - if obj.kind_of? Proc - methods << name - else - obj.class.public_instance_methods(false).each do |meth| - methods << "#{name}#{meth}" - end - end - end - methods - end - - add_handler("system.methodSignature", %w(array string), "Returns method signature") do |meth| - sigs = [] - @handler.each do |name, obj, sig| - if obj.kind_of? Proc and sig != nil and name == meth - if sig[0].kind_of? Array - # sig contains multiple signatures, e.g. [["array"], ["array", "string"]] - sig.each {|s| sigs << s} - else - # sig is a single signature, e.g. ["array"] - sigs << sig - end - end - end - sigs.uniq! || sigs # remove eventually duplicated signatures - end - - add_handler("system.methodHelp", %w(string string), "Returns help on using this method") do |meth| - help = nil - @handler.each do |name, obj, sig, hlp| - if obj.kind_of? Proc and name == meth - help = hlp - break - end - end - help || "" - end - - self - end - - - - def process(data) - method, params = parser().parseMethodCall(data) - handle(method, *params) - end - - private - - def multicall_fault(nr, str) - {"faultCode" => nr, "faultString" => str} - end - - def dispatch(methodname, *args) - for name, obj in @handler - if obj.kind_of? Proc - next unless methodname == name - else - next unless methodname =~ /^#{name}(.+)$/ - next unless obj.respond_to? $1 - obj = obj.method($1) - end - - if check_arity(obj, args.size) - if @service_hook.nil? - return obj.call(*args) - else - return @service_hook.call(obj, *args) - 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) - end - end - - - # Returns +true+, if the arity of +obj+ matches +n_args+ - def check_arity(obj, n_args) - ary = obj.arity - - if ary >= 0 - n_args == ary - else - n_args >= (ary+1).abs - end - end - - - - def call_method(methodname, *args) - begin - [true, dispatch(methodname, *args)] - rescue XMLRPC::FaultException => e - [false, e] - rescue Exception => e - [false, XMLRPC::FaultException.new(ERR_UNCAUGHT_EXCEPTION, "Uncaught exception #{e.message} in method #{methodname}")] - end - end - - def handle(methodname, *args) - create().methodResponse(*call_method(methodname, *args)) - end - - -end - - -# Implements a CGI-based XML-RPC server. -# -# require "xmlrpc/server" -# -# s = XMLRPC::CGIServer.new -# -# s.add_handler("michael.add") do |a,b| -# a + b -# end -# -# s.add_handler("michael.div") do |a,b| -# if b == 0 -# raise XMLRPC::FaultException.new(1, "division by zero") -# else -# a / b -# 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 -# -# -# Note: Make sure that you don't write to standard-output in a -# handler, or in any other part of your program, this would cause a CGI-based -# server to fail! -class CGIServer < BasicServer - @@obj = nil - - # Creates a new XMLRPC::CGIServer instance. - # - # All parameters given are by-passed to XMLRPC::BasicServer.new. - # - # You can only create one XMLRPC::CGIServer instance, because more - # than one makes no sense. - def CGIServer.new(*a) - @@obj = super(*a) if @@obj.nil? - @@obj - end - - def initialize(*a) - super(*a) - end - - # Call this after you have added all you handlers to the server. - # - # This method processes a XML-RPC method call and sends the answer - # back to the client. - def serve - catch(:exit_serve) { - length = ENV['CONTENT_LENGTH'].to_i - - 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 - - # TODO: do we need a call to binmode? - $stdin.binmode if $stdin.respond_to? :binmode - data = $stdin.read(length) - - http_error(400, "Bad Request") if data.nil? or data.bytesize != length - - http_write(process(data), "Content-type" => "text/xml; charset=utf-8") - } - end - - - private - - def http_error(status, message) - err = "#{status} #{message}" - msg = <<-"MSGEND" - - - #{err} - - -

#{err}

-

Unexpected error occurred while processing XML-RPC request!

- - - MSGEND - - http_write(msg, "Status" => err, "Content-type" => "text/html") - throw :exit_serve # exit from the #serve method - end - - def http_write(body, header) - h = {} - header.each {|key, value| h[key.to_s.capitalize] = value} - h['Status'] ||= "200 OK" - h['Content-length'] ||= body.bytesize.to_s - - str = "" - h.each {|key, value| str << "#{key}: #{value}\r\n"} - str << "\r\n#{body}" - - print str - end - -end - - -# Implements a XML-RPC server, which works with Apache mod_ruby. -# -# Use it in the same way as XMLRPC::CGIServer! -class ModRubyServer < BasicServer - - # Creates a new XMLRPC::ModRubyServer instance. - # - # All parameters given are by-passed to XMLRPC::BasicServer.new. - def initialize(*a) - @ap = Apache::request - super(*a) - end - - # Call this after you have added all you handlers to the server. - # - # This method processes a XML-RPC method call and sends the answer - # back to the client. - def serve - catch(:exit_serve) { - header = {} - @ap.headers_in.each {|key, value| header[key.capitalize] = value} - - length = header['Content-length'].to_i - - 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 - - # TODO: do we need a call to binmode? - @ap.binmode - data = @ap.read(length) - - http_error(400, "Bad Request") if data.nil? or data.bytesize != length - - http_write(process(data), 200, "Content-type" => "text/xml; charset=utf-8") - } - end - - - private - - def http_error(status, message) - err = "#{status} #{message}" - msg = <<-"MSGEND" - - - #{err} - - -

#{err}

-

Unexpected error occurred while processing XML-RPC request!

- - - MSGEND - - http_write(msg, status, "Status" => err, "Content-type" => "text/html") - throw :exit_serve # exit from the #serve method - end - - def http_write(body, status, header) - h = {} - header.each {|key, value| h[key.to_s.capitalize] = value} - h['Status'] ||= "200 OK" - h['Content-length'] ||= body.bytesize.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.print body - end - -end - - -class WEBrickServlet < BasicServer; end # forward declaration - -# Implements a standalone XML-RPC server. The method XMLRPC::Server#serve is -# left if a SIGHUP is sent to the program. -# -# require "xmlrpc/server" -# -# s = XMLRPC::Server.new(8080) -# -# s.add_handler("michael.add") do |a,b| -# a + b -# end -# -# s.add_handler("michael.div") do |a,b| -# if b == 0 -# raise XMLRPC::FaultException.new(1, "division by zero") -# else -# a / b -# 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 -class Server < WEBrickServlet - - # Creates a new XMLRPC::Server instance, which is a XML-RPC server - # listening on the given +port+ and accepts requests for the given +host+, - # which is +localhost+ by default. - # - # The server is not started, to start it you have to call - # XMLRPC::Server#serve. - # - # The optional +audit+ and +debug+ parameters are obsolete! - # - # All additionally provided parameters in *a are by-passed to - # XMLRPC::BasicServer.new. - 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, - :Logger => WEBrick::Log.new(stdlog)) - @server.mount("/", self) - end - - # Call this after you have added all you handlers to the server. - # This method starts the server to listen for XML-RPC requests and answer them. - def serve - signals = %w[INT TERM HUP] & Signal.list.keys - signals.each { |signal| trap(signal) { @server.shutdown } } - - @server.start - end - - # Stops and shuts the server down. - def shutdown - @server.shutdown - end - -end - - -# Implements a servlet for use with WEBrick, a pure Ruby (HTTP) server -# framework. -# -# require "webrick" -# require "xmlrpc/server" -# -# s = XMLRPC::WEBrickServlet.new -# s.add_handler("michael.add") do |a,b| -# a + b -# end -# -# s.add_handler("michael.div") do |a,b| -# if b == 0 -# raise XMLRPC::FaultException.new(1, "division by zero") -# else -# a / b -# 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.mount("/RPC2", s) -# trap("HUP") { httpserver.shutdown } # use 1 instead of "HUP" on Windows -# httpserver.start -class WEBrickServlet < BasicServer - def initialize(*a) - super - require "webrick/httpstatus" - @valid_ip = nil - end - - # Deprecated from WEBrick/1.2.2, but does not break anything. - def require_path_info? - false - end - - def get_instance(config, *options) - # TODO: set config & options - self - end - - # Specifies the valid IP addresses that are allowed to connect to the server. - # - # Each IP is either a String or a Regexp. - def set_valid_ip(*ip_addr) - if ip_addr.size == 1 and ip_addr[0].nil? - @valid_ip = nil - else - @valid_ip = ip_addr - end - end - - # Return the valid IP addresses that are allowed to connect to the server. - # - # See also, XMLRPC::Server#set_valid_ip - def get_valid_ip - @valid_ip - end - - def service(request, response) - - if @valid_ip - raise WEBrick::HTTPStatus::Forbidden unless @valid_ip.any? { |ip| request.peeraddr[3] =~ ip } - end - - if request.request_method != "POST" - raise WEBrick::HTTPStatus::MethodNotAllowed, - "unsupported method `#{request.request_method}'." - end - - if parse_content_type(request['Content-type']).first != "text/xml" - raise WEBrick::HTTPStatus::BadRequest - end - - length = (request['Content-length'] || 0).to_i - - raise WEBrick::HTTPStatus::LengthRequired unless length > 0 - - data = request.body - - if data.nil? or data.bytesize != length - raise WEBrick::HTTPStatus::BadRequest - end - - resp = process(data) - if resp.nil? or resp.bytesize <= 0 - raise WEBrick::HTTPStatus::InternalServerError - end - - response.status = 200 - response['Content-Length'] = resp.bytesize - response['Content-Type'] = "text/xml; charset=utf-8" - response.body = resp - end -end - - -end # module XMLRPC - - -=begin -= History - $Id$ -=end - diff --git a/lib/xmlrpc/utils.rb b/lib/xmlrpc/utils.rb deleted file mode 100644 index cd2ab107d9..0000000000 --- a/lib/xmlrpc/utils.rb +++ /dev/null @@ -1,172 +0,0 @@ -# frozen_string_literal: false -# -# Copyright (C) 2001, 2002, 2003 by Michael Neumann (mneumann@ntecs.de) -# -# $Id$ -# -module XMLRPC # :nodoc: - - - # This module enables a user-class to be marshalled - # by XML-RPC for Ruby into a Hash, with one additional - # key/value pair ___class___ => ClassName - # - module Marshallable - end - - - # Defines ParserWriterChooseMixin, which makes it possible to choose a - # different XMLWriter and/or XMLParser then the default one. - # - # The Mixin is used in client.rb (class XMLRPC::Client) - # and server.rb (class XMLRPC::BasicServer) - module ParserWriterChooseMixin - - # Sets the XMLWriter 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. - def set_writer(writer) - @create = Create.new(writer) - self - end - - # Sets the XMLParser to use for parsing XML documents. - # - # Should be an instance of a class from module XMLRPC::XMLParser. - # - # If this method is not called, then XMLRPC::Config::DEFAULT_PARSER is used. - def set_parser(parser) - @parser = parser - self - end - - private - - def create - # if set_writer was not already called then call it now - if @create.nil? then - set_writer(Config::DEFAULT_WRITER.new) - end - @create - end - - def parser - # if set_parser was not already called then call it now - if @parser.nil? then - set_parser(Config::DEFAULT_PARSER.new) - end - @parser - end - - end # module ParserWriterChooseMixin - - - module Service - - # Base class for XMLRPC::Service::Interface definitions, used - # by XMLRPC::BasicServer#add_handler - class BasicInterface - attr_reader :prefix, :methods - - def initialize(prefix) - @prefix = prefix - @methods = [] - end - - def add_method(sig, help=nil, meth_name=nil) - mname = nil - sig = [sig] if sig.kind_of? String - - sig = sig.collect do |s| - name, si = parse_sig(s) - raise "Wrong signatures!" if mname != nil and name != mname - mname = name - si - end - - @methods << [mname, meth_name || mname, sig, help] - end - - private - - def parse_sig(sig) - # sig is a String - if sig =~ /^\s*(\w+)\s+([^(]+)(\(([^)]*)\))?\s*$/ - params = [$1] - name = $2.strip - $4.split(",").each {|i| params << i.strip} if $4 != nil - return name, params - else - raise "Syntax error in signature" - end - end - - end # class BasicInterface - - # - # Class which wraps a XMLRPC::Service::Interface definition, used - # by XMLRPC::BasicServer#add_handler - # - class Interface < BasicInterface - def initialize(prefix, &p) - raise "No interface specified" if p.nil? - super(prefix) - instance_eval(&p) - end - - def get_methods(obj, delim=".") - prefix = @prefix + delim - @methods.collect { |name, meth, sig, help| - [prefix + name.to_s, obj.method(meth).to_proc, sig, help] - } - end - - private - - def meth(*a) - add_method(*a) - end - - end # class Interface - - class PublicInstanceMethodsInterface < BasicInterface - def initialize(prefix) - super(prefix) - end - - def get_methods(obj, delim=".") - prefix = @prefix + delim - obj.class.public_instance_methods(false).collect { |name| - [prefix + name.to_s, obj.method(name).to_proc, nil, nil] - } - end - end - - - end # module Service - - - # - # Short-form to create a XMLRPC::Service::Interface - # - def self.interface(prefix, &p) - Service::Interface.new(prefix, &p) - end - - # Short-cut for creating a XMLRPC::Service::PublicInstanceMethodsInterface - def self.iPIMethods(prefix) - Service::PublicInstanceMethodsInterface.new(prefix) - end - - - module ParseContentType - def parse_content_type(str) - a, *b = str.split(";") - return a.strip.downcase, *b - end - end - -end # module XMLRPC - diff --git a/test/xmlrpc/data/blog.xml b/test/xmlrpc/data/blog.xml deleted file mode 100644 index cb325f1803..0000000000 --- a/test/xmlrpc/data/blog.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - - isAdmin1 - urlhttp://tenderlovemaking.com/ - blogid1 - blogNameTender Lovemaking - xmlrpchttp://tenderlovemaking.com/xmlrpc.php - - - - - - diff --git a/test/xmlrpc/data/bug_bool.expected b/test/xmlrpc/data/bug_bool.expected deleted file mode 100644 index 121e3a84ba..0000000000 --- a/test/xmlrpc/data/bug_bool.expected +++ /dev/null @@ -1,3 +0,0 @@ ---- -- true -- false \ No newline at end of file diff --git a/test/xmlrpc/data/bug_bool.xml b/test/xmlrpc/data/bug_bool.xml deleted file mode 100644 index 04ed00709e..0000000000 --- a/test/xmlrpc/data/bug_bool.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - 0 - - - diff --git a/test/xmlrpc/data/bug_cdata.expected b/test/xmlrpc/data/bug_cdata.expected deleted file mode 100644 index 17d7861318..0000000000 --- a/test/xmlrpc/data/bug_cdata.expected +++ /dev/null @@ -1,3 +0,0 @@ ---- -- true -- test \ No newline at end of file diff --git a/test/xmlrpc/data/bug_cdata.xml b/test/xmlrpc/data/bug_cdata.xml deleted file mode 100644 index ba990e04f1..0000000000 --- a/test/xmlrpc/data/bug_cdata.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - - - - diff --git a/test/xmlrpc/data/bug_covert.expected b/test/xmlrpc/data/bug_covert.expected deleted file mode 100644 index a9ac103c64..0000000000 --- a/test/xmlrpc/data/bug_covert.expected +++ /dev/null @@ -1,10 +0,0 @@ ---- -- true -- > - Site,SANs,Array - - Configured Capacity,Array Reserved Capacity,Array Ava - - ilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host % - - Used diff --git a/test/xmlrpc/data/bug_covert.xml b/test/xmlrpc/data/bug_covert.xml deleted file mode 100644 index 1d9abd2a06..0000000000 --- a/test/xmlrpc/data/bug_covert.xml +++ /dev/null @@ -1,6 +0,0 @@ -Site,SANs,Array -Configured Capacity,Array Reserved Capacity,Array Ava -ilable Capacity,Array % Reserved,Host Allocated,Host Used,Host Free,Host % -Used - diff --git a/test/xmlrpc/data/datetime_iso8601.xml b/test/xmlrpc/data/datetime_iso8601.xml deleted file mode 100644 index 43d8da6c13..0000000000 --- a/test/xmlrpc/data/datetime_iso8601.xml +++ /dev/null @@ -1,8 +0,0 @@ - - - - - 20041105T01:15:23Z - - - diff --git a/test/xmlrpc/data/fault.xml b/test/xmlrpc/data/fault.xml deleted file mode 100644 index 041c464eb3..0000000000 --- a/test/xmlrpc/data/fault.xml +++ /dev/null @@ -1,16 +0,0 @@ - - - - - - faultCode - 4 - - - faultString - an error message - - - - - diff --git a/test/xmlrpc/data/value.expected b/test/xmlrpc/data/value.expected deleted file mode 100644 index 9463d02b13..0000000000 --- a/test/xmlrpc/data/value.expected +++ /dev/null @@ -1,7 +0,0 @@ ---- -- Test -- - - Hallo Leute - - " Hallo " - - '' - - " " \ No newline at end of file diff --git a/test/xmlrpc/data/value.xml b/test/xmlrpc/data/value.xml deleted file mode 100644 index 1978616099..0000000000 --- a/test/xmlrpc/data/value.xml +++ /dev/null @@ -1,22 +0,0 @@ - - - Test - - - Hallo Leute - - - Hallo - - - - - - - - - - - - - diff --git a/test/xmlrpc/data/xml1.expected b/test/xmlrpc/data/xml1.expected deleted file mode 100644 index ff96de8df3..0000000000 --- a/test/xmlrpc/data/xml1.expected +++ /dev/null @@ -1,243 +0,0 @@ ---- -- true -- - - - subscriber: MegaCorp - lastName: Baker - telephone1: 1-508-791-1267 - telephone2: 1-800-445-2588 - password: p1111 - OID: "1" - email: hbaker@yahoo.com - adminId: hbaker - objectName: AdministratorDO - - - subscriber: CornerStore - lastName: Dragon - telephone1: 1-781-789-9089 - telephone2: 1-800-445-2588 - password: p3333 - OID: "3" - email: adragon@yahoo.com - adminId: adragon - objectName: AdministratorDO - - - subscriber: Cyberdyne - lastName: Rodman - telephone1: 1-617-789-1890 - telephone2: 1-800-445-2588 - password: p4444 - OID: "4" - email: mrodman@yahoo.com - adminId: mrodman - objectName: AdministratorDO - - - subscriber: StarSports - lastName: Jordan - telephone1: 1-617-890-7897 - telephone2: 1-800-445-2588 - password: p5555 - OID: "5" - email: mjordan@yahoo.com - adminId: mjordan - objectName: AdministratorDO - - - subscriber: GreatBooks - lastName: Pippen - telephone1: 1-781-789-9876 - telephone2: 1-800-445-2588 - password: p6666 - OID: "6" - email: gpippen@yahoo.com - adminId: gpippen - objectName: AdministratorDO - - - subscriber: AxisChemicals - lastName: Andhrew - telephone1: 1-781-678-8970 - telephone2: 1-800-445-2588 - password: p7777 - OID: "7" - email: aandrew@yahoo.com - adminId: aandrew - objectName: AdministratorDO - - - subscriber: MediaShop - lastName: Vincent - telephone1: 1-786-897-8908 - telephone2: 1-800-445-2588 - password: p8888 - OID: "8" - email: tvincent@yahoo.com - adminId: tvincent - objectName: AdministratorDO - - - subscriber: SmartShop - lastName: Richard - telephone1: 1-508-789-6789 - telephone2: 1-800-445-2588 - password: p9999 - OID: "9" - email: krichard@yahoo.com - adminId: krichard - objectName: AdministratorDO - - - subscriber: HomeNeeds - lastName: Cornell - telephone1: 1-617-789-8979 - telephone2: 1-800-445-2588 - password: paaaa - OID: "10" - email: gconell@yahoo.com - adminId: gcornell - objectName: AdministratorDO - - - subscriber: MegaCorp - lastName: HorstMann - telephone1: 1-508-791-1267 - telephone2: 1-800-445-2588 - password: p1111 - OID: "11" - email: shorstmann@yahoo.com - adminId: shorstmann - objectName: AdministratorDO - - - subscriber: CornerStore - lastName: Bob - telephone1: 1-781-789-9089 - telephone2: 1-800-445-2588 - password: p3333 - OID: "13" - email: rbob@yahoo.com - adminId: rbob - objectName: AdministratorDO - - - subscriber: Cyberdyne - lastName: Peter - telephone1: 1-617-789-1890 - telephone2: 1-800-445-2588 - password: p4444 - OID: "14" - email: speter@yahoo.com - adminId: speter - objectName: AdministratorDO - - - subscriber: StarSports - lastName: Novak - telephone1: 1-617-890-7897 - telephone2: 1-800-445-2588 - password: p5555 - OID: "15" - email: pnovak@yahoo.com - adminId: pnovak - objectName: AdministratorDO - - - subscriber: GreatBooks - lastName: Nancy - telephone1: 1-781-789-9876 - telephone2: 1-800-445-2588 - password: p6666 - OID: "16" - email: pnancy@yahoo.com - adminId: pnancy - objectName: AdministratorDO - - - subscriber: AxisChemicals - lastName: Michel - telephone1: 1-781-678-8970 - telephone2: 1-800-445-2588 - password: p7777 - OID: "17" - email: hmichel@yahoo.com - adminId: hmichel - objectName: AdministratorDO - - - subscriber: MediaShop - lastName: David - telephone1: 1-786-897-8908 - telephone2: 1-800-445-2588 - password: p8888 - OID: "18" - email: kdavid@yahoo.com - adminId: kdavid - objectName: AdministratorDO - - - subscriber: SmartShop - lastName: Valnoor - telephone1: 1-508-789-6789 - telephone2: 1-800-445-2588 - password: p9999 - OID: "19" - email: pvalnoor@yahoo.com - adminId: pvalnoor - objectName: AdministratorDO - - - subscriber: HomeNeeds - lastName: Smith - telephone1: 1-617-789-8979 - telephone2: 1-800-445-2588 - password: paaaa - OID: "20" - email: wsmith@yahoo.com - adminId: wsmith - objectName: AdministratorDO - - - subscriber: MegaCorp - lastName: Caral - telephone1: 1-781-789-9876 - telephone2: 1-800-445-2588 - password: p6666 - OID: "21" - email: gcaral@yahoo.com - adminId: gcaral - objectName: AdministratorDO - - - subscriber: CornerStore - lastName: Hillary - telephone1: 1-786-897-8908 - telephone2: 1-800-445-2588 - password: p8888 - OID: "23" - email: phillary@yahoo.com - adminId: phillary - objectName: AdministratorDO - - - subscriber: Cyberdyne - lastName: Philip - telephone1: 1-508-789-6789 - telephone2: 1-800-445-2588 - password: p9999 - OID: "24" - email: bphilip@yahoo.com - adminId: bphilip - objectName: AdministratorDO - - - subscriber: StarSports - lastName: Andrea - telephone1: 1-617-789-8979 - telephone2: 1-800-445-2588 - password: paaaa - OID: "25" - email: sandrea@yahoo.com - adminId: sandrea - objectName: AdministratorDO - - - subscriber: s4 - lastName: "null" - telephone1: "null" - telephone2: "null" - password: s4 - OID: "26" - email: "null" - adminId: s4 - objectName: AdministratorDO - - - subscriber: BigBank - lastName: administrator - telephone1: '' - telephone2: '' - password: admin - OID: "82" - email: '' - adminId: admin - objectName: AdministratorDO \ No newline at end of file diff --git a/test/xmlrpc/data/xml1.xml b/test/xmlrpc/data/xml1.xml deleted file mode 100644 index 10aa55483b..0000000000 --- a/test/xmlrpc/data/xml1.xml +++ /dev/null @@ -1 +0,0 @@ -objectNameAdministratorDOadminIdhbakeremailhbaker@yahoo.comtelephone21-800-445-2588telephone11-508-791-1267OID1passwordp1111lastNameBakersubscriberMegaCorpobjectNameAdministratorDOadminIdadragonemailadragon@yahoo.comtelephone21-800-445-2588telephone11-781-789-9089OID3passwordp3333lastNameDragonsubscriberCornerStoreobjectNameAdministratorDOadminIdmrodmanemailmrodman@yahoo.comtelephone21-800-445-2588telephone11-617-789-1890OID4passwordp4444lastNameRodmansubscriberCyberdyneobjectNameAdministratorDOadminIdmjordanemailmjordan@yahoo.comtelephone21-800-445-2588telephone11-617-890-7897OID5passwordp5555lastNameJordansubscriberStarSportsobjectNameAdministratorDOadminIdgpippenemailgpippen@yahoo.comtelephone21-800-445-2588telephone11-781-789-9876OID6passwordp6666lastNamePippensubscriberGreatBooksobjectNameAdministratorDOadminIdaandrewemailaandrew@yahoo.comtelephone21-800-445-2588telephone11-781-678-8970OID7passwordp7777lastNameAndhrewsubscriberAxisChemicalsobjectNameAdministratorDOadminIdtvincentemailtvincent@yahoo.comtelephone21-800-445-2588telephone11-786-897-8908OID8passwordp8888lastNameVincentsubscriberMediaShopobjectNameAdministratorDOadminIdkrichardemailkrichard@yahoo.comtelephone21-800-445-2588telephone11-508-789-6789OID9passwordp9999lastNameRichardsubscriberSmartShopobjectNameAdministratorDOadminIdgcornellemailgconell@yahoo.comtelephone21-800-445-2588telephone11-617-789-8979OID10passwordpaaaalastNameCornellsubscriberHomeNeedsobjectNameAdministratorDOadminIdshorstmannemailshorstmann@yahoo.comtelephone21-800-445-2588telephone11-508-791-1267OID11passwordp1111lastNameHorstMannsubscriberMegaCorpobjectNameAdministratorDOadminIdrbobemailrbob@yahoo.comtelephone21-800-445-2588telephone11-781-789-9089OID13passwordp3333lastNameBobsubscriberCornerStoreobjectNameAdministratorDOadminIdspeteremailspeter@yahoo.comtelephone21-800-445-2588telephone11-617-789-1890OID14passwordp4444lastNamePetersubscriberCyberdyneobjectNameAdministratorDOadminIdpnovakemailpnovak@yahoo.comtelephone21-800-445-2588telephone11-617-890-7897OID15passwordp5555lastNameNovaksubscriberStarSportsobjectNameAdministratorDOadminIdpnancyemailpnancy@yahoo.comtelephone21-800-445-2588telephone11-781-789-9876OID16passwordp6666lastNameNancysubscriberGreatBooksobjectNameAdministratorDOadminIdhmichelemailhmichel@yahoo.comtelephone21-800-445-2588telephone11-781-678-8970OID17passwordp7777lastNameMichelsubscriberAxisChemicalsobjectNameAdministratorDOadminIdkdavidemailkdavid@yahoo.comtelephone21-800-445-2588telephone11-786-897-8908OID18passwordp8888lastNameDavidsubscriberMediaShopobjectNameAdministratorDOadminIdpvalnooremailpvalnoor@yahoo.comtelephone21-800-445-2588telephone11-508-789-6789OID19passwordp9999lastNameValnoorsubscriberSmartShopobjectNameAdministratorDOadminIdwsmithemailwsmith@yahoo.comtelephone21-800-445-2588telephone11-617-789-8979OID20passwordpaaaalastNameSmithsubscriberHomeNeedsobjectNameAdministratorDOadminIdgcaralemailgcaral@yahoo.comtelephone21-800-445-2588telephone11-781-789-9876OID21passwordp6666lastNameCaralsubscriberMegaCorpobjectNameAdministratorDOadminIdphillaryemailphillary@yahoo.comtelephone21-800-445-2588telephone11-786-897-8908OID23passwordp8888lastNameHillarysubscriberCornerStoreobjectNameAdministratorDOadminIdbphilipemailbphilip@yahoo.comtelephone21-800-445-2588telephone11-508-789-6789OID24passwordp9999lastNamePhilipsubscriberCyberdyneobjectNameAdministratorDOadminIdsandreaemailsandrea@yahoo.comtelephone21-800-445-2588telephone11-617-789-8979OID25passwordpaaaalastNameAndreasubscriberStarSportsobjectNameAdministratorDOadminIds4emailnulltelephone2nulltelephone1nullOID26passwords4lastNamenullsubscribers4objectNameAdministratorDOadminIdadminemailtelephone2telephone1OID82passwordadminlastNameadministratorsubscriberBigBank diff --git a/test/xmlrpc/htpasswd b/test/xmlrpc/htpasswd deleted file mode 100644 index 898fc8663b..0000000000 --- a/test/xmlrpc/htpasswd +++ /dev/null @@ -1,2 +0,0 @@ -admin:Qg266hq/YYKe2 -01234567890123456789012345678901234567890123456789012345678901234567890123456789:Yl.SJmoFETpS2 diff --git a/test/xmlrpc/test_client.rb b/test/xmlrpc/test_client.rb deleted file mode 100644 index 634de02d4d..0000000000 --- a/test/xmlrpc/test_client.rb +++ /dev/null @@ -1,323 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require 'xmlrpc/client' -require 'net/http' -begin - require 'openssl' -rescue LoadError -end - -module XMLRPC - class ClientTest < Test::Unit::TestCase - module Fake - class HTTP < Net::HTTP - class << self - def new(*args, &block) - Class.method(:new).unbind.bind(self).call(*args, &block) - end - end - - def initialize responses = {} - super("127.0.0.1") - @started = false - @responses = responses - end - - def started? - @started - end - - def start - @started = true - if block_given? - begin - return yield(self) - ensure - @started = false - end - end - self - end - - def request_post path, request, headers - @responses[path].shift - end - end - - class Client < XMLRPC::Client - attr_reader :args, :http - - def initialize(*args) - @args = args - super - end - - private - def net_http host, port, proxy_host, proxy_port - HTTP.new - end - end - - class Response - def self.new body, fields = [], status = '200' - klass = Class.new(Net::HTTPResponse::CODE_TO_OBJ[status]) { - def initialize(*args) - super - @read = true - end - } - - resp = klass.new '1.1', status, 'OK' - resp.body = body - fields.each do |k,v| - resp.add_field k, v - end - resp - end - end - end - - def test_new2_host_path_port - client = Fake::Client.new2 'http://example.org/foo' - host, path, port, *rest = client.args - - assert_equal 'example.org', host - assert_equal '/foo', path - assert_equal 80, port - - rest.each { |x| refute x } - end - - def test_new2_custom_port - client = Fake::Client.new2 'http://example.org:1234/foo' - host, path, port, *rest = client.args - - assert_equal 'example.org', host - assert_equal '/foo', path - assert_equal 1234, port - - rest.each { |x| refute x } - end - - def test_new2_ssl - client = Fake::Client.new2 'https://example.org/foo' - host, path, port, proxy_host, proxy_port, user, password, use_ssl, timeout = client.args - - assert_equal 'example.org', host - assert_equal '/foo', path - assert_equal 443, port - assert use_ssl - - refute proxy_host - refute proxy_port - refute user - refute password - refute timeout - end if defined?(OpenSSL) - - def test_new2_ssl_custom_port - client = Fake::Client.new2 'https://example.org:1234/foo' - host, path, port, proxy_host, proxy_port, user, password, use_ssl, timeout = client.args - - assert_equal 'example.org', host - assert_equal '/foo', path - assert_equal 1234, port - assert use_ssl - - refute proxy_host - refute proxy_port - refute user - refute password - refute timeout - end if defined?(OpenSSL) - - def test_new2_user_password - client = Fake::Client.new2 'http://aaron:tenderlove@example.org/foo' - host, path, port, proxy_host, proxy_port, user, password, use_ssl, timeout = client.args - - [ host, path, port ].each { |x| assert x } - assert_equal 'aaron', user - assert_equal 'tenderlove', password - - [ proxy_host, proxy_port, use_ssl, timeout ].each { |x| refute x } - end - - def test_new2_proxy_host - client = Fake::Client.new2 'http://example.org/foo', 'example.com' - host, path, port, proxy_host, proxy_port, user, password, use_ssl, timeout = client.args - - [ host, path, port ].each { |x| assert x } - - assert_equal 'example.com', proxy_host - - [ user, password, proxy_port, use_ssl, timeout ].each { |x| refute x } - end - - def test_new2_proxy_port - client = Fake::Client.new2 'http://example.org/foo', 'example.com:1234' - host, path, port, proxy_host, proxy_port, user, password, use_ssl, timeout = client.args - - [ host, path, port ].each { |x| assert x } - - assert_equal 'example.com', proxy_host - assert_equal 1234, proxy_port - - [ user, password, use_ssl, timeout ].each { |x| refute x } - end - - def test_new2_no_path - client = Fake::Client.new2 'http://example.org' - host, path, port, *rest = client.args - - assert_equal 'example.org', host - assert_nil path - assert port - - rest.each { |x| refute x } - end - - def test_new2_slash_path - client = Fake::Client.new2 'http://example.org/' - host, path, port, *rest = client.args - - assert_equal 'example.org', host - assert_equal '/', path - assert port - - rest.each { |x| refute x } - end - - def test_new2_bad_protocol - assert_raise(ArgumentError) do - XMLRPC::Client.new2 'ftp://example.org' - end - end - - def test_new2_bad_uri - assert_raise(ArgumentError) do - XMLRPC::Client.new2 ':::::' - end - end - - def test_new2_path_with_query - client = Fake::Client.new2 'http://example.org/foo?bar=baz' - host, path, port, *rest = client.args - - assert_equal 'example.org', host - assert_equal '/foo?bar=baz', path - assert port - - rest.each { |x| refute x } - end - - def test_request - fh = read 'blog.xml' - - responses = { - '/foo' => [ Fake::Response.new(fh, [['Content-Type', 'text/xml']]) ] - } - - client = fake_client(responses).new2 'http://example.org/foo' - - resp = client.call('wp.getUsersBlogs', 'tlo', 'omg') - - expected = [{ - "isAdmin" => true, - "url" => "http://tenderlovemaking.com/", - "blogid" => "1", - "blogName" => "Tender Lovemaking", - "xmlrpc" => "http://tenderlovemaking.com/xmlrpc.php" - }] - - assert_equal expected, resp - end - - def test_async_request - fh = read 'blog.xml' - - responses = { - '/foo' => [ Fake::Response.new(fh, [['Content-Type', 'text/xml']]) ] - } - - client = fake_client(responses).new2 'http://example.org/foo' - - resp = client.call_async('wp.getUsersBlogs', 'tlo', 'omg') - - expected = [{ - "isAdmin" => true, - "url" => "http://tenderlovemaking.com/", - "blogid" => "1", - "blogName" => "Tender Lovemaking", - "xmlrpc" => "http://tenderlovemaking.com/xmlrpc.php" - }] - - assert_equal expected, resp - end - - # make a request without content-type header - def test_bad_content_type - fh = read 'blog.xml' - - responses = { - '/foo' => [ Fake::Response.new(fh) ] - } - - client = fake_client(responses).new2 'http://example.org/foo' - - resp = client.call('wp.getUsersBlogs', 'tlo', 'omg') - - expected = [{ - "isAdmin" => true, - "url" => "http://tenderlovemaking.com/", - "blogid" => "1", - "blogName" => "Tender Lovemaking", - "xmlrpc" => "http://tenderlovemaking.com/xmlrpc.php" - }] - - assert_equal expected, resp - end - - def test_i8_tag - fh = read('blog.xml').gsub(/string/, 'i8') - - responses = { - '/foo' => [ Fake::Response.new(fh) ] - } - - client = fake_client(responses).new2 'http://example.org/foo' - - resp = client.call('wp.getUsersBlogs', 'tlo', 'omg') - - assert_equal 1, resp.first['blogid'] - end - - def test_cookie_simple - client = Fake::Client.new2('http://example.org/cookie') - assert_nil(client.cookie) - client.send(:parse_set_cookies, ["param1=value1", "param2=value2"]) - assert_equal("param1=value1; param2=value2", client.cookie) - end - - def test_cookie_override - client = Fake::Client.new2('http://example.org/cookie') - client.send(:parse_set_cookies, - [ - "param1=value1", - "param2=value2", - "param1=value3", - ]) - assert_equal("param2=value2; param1=value3", client.cookie) - end - - private - def read filename - File.read File.expand_path(File.join(__FILE__, '..', 'data', filename)) - end - - def fake_client responses - Class.new(Fake::Client) { - define_method(:net_http) { |*_| Fake::HTTP.new(responses) } - } - end - end -end diff --git a/test/xmlrpc/test_cookie.rb b/test/xmlrpc/test_cookie.rb deleted file mode 100644 index 32eedca367..0000000000 --- a/test/xmlrpc/test_cookie.rb +++ /dev/null @@ -1,97 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require 'time' -require 'webrick' -require_relative 'webrick_testing' -require "xmlrpc/server" -require 'xmlrpc/client' - -module TestXMLRPC -class TestCookie < Test::Unit::TestCase - include WEBrick_Testing - - def create_servlet - s = XMLRPC::WEBrickServlet.new - - def s.logged_in_users - @logged_in_users ||= {} - end - def s.request - @request - end - def s.response - @response - end - def s.service(request, response) - @request = request - @response = response - super - ensure - @request = nil - @response = nil - end - - key = Time.now.to_i.to_s - valid_user = "valid-user" - s.add_handler("test.login") do |user, password| - ok = (user == valid_user and password == "secret") - if ok - s.logged_in_users[key] = user - expires = (Time.now + 60 * 60).httpdate - cookies = s.response.cookies - cookies << "key=\"#{key}\"; path=\"/RPC2\"; expires=#{expires}" - cookies << "user=\"#{user}\"; path=\"/RPC2\"" - end - ok - end - - s.add_handler("test.require_authenticate_echo") do |string| - cookies = {} - s.request.cookies.each do |cookie| - cookies[cookie.name] = cookie.value - end - if cookies == {"key" => key, "user" => valid_user} - string - else - raise XMLRPC::FaultException.new(29, "Authentication required") - end - end - - s.set_default_handler do |name, *args| - raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + - " or wrong number of parameters!") - end - - s.add_introspection - - s - end - - def setup_http_server_option - option = {:Port => 0} - end - - def test_cookie - option = setup_http_server_option - with_server(option, create_servlet) {|addr| - begin - @s = XMLRPC::Client.new3(:host => addr.ip_address, :port => addr.ip_port) - do_test - ensure - @s.http.finish - end - } - end - - def do_test - assert(!@s.call("test.login", "invalid-user", "invalid-password")) - exception = assert_raise(XMLRPC::FaultException) do - @s.call("test.require_authenticate_echo", "Hello") - end - assert_equal(29, exception.faultCode) - - assert(@s.call("test.login", "valid-user", "secret")) - assert_equal("Hello", @s.call("test.require_authenticate_echo", "Hello")) - end -end -end diff --git a/test/xmlrpc/test_datetime.rb b/test/xmlrpc/test_datetime.rb deleted file mode 100644 index 6a46e15f84..0000000000 --- a/test/xmlrpc/test_datetime.rb +++ /dev/null @@ -1,162 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require "xmlrpc/datetime" - -module TestXMLRPC -class Test_DateTime < Test::Unit::TestCase - - def test_new - dt = createDateTime() - - assert_instance_of(XMLRPC::DateTime, dt) - end - - def test_new_exception - assert_raise(ArgumentError) { XMLRPC::DateTime.new(4.5, 13, 32, 25, 60, 60) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 32, 25, 60, 60) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 25, 60, 60) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 60, 60) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 60) } - assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 12, 31, 24, 59, 59) } - - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 0, 0, -1, -1, -1) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 0, -1, -1, -1) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, -1, -1, -1) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, -1, -1) } - assert_raise(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, -1) } - assert_nothing_raised(ArgumentError) { XMLRPC::DateTime.new(2001, 1, 1, 0, 0, 0) } - end - - - def test_get_values - y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5 - dt = XMLRPC::DateTime.new(y, m, d, h, mi, s) - - assert_equal(y, dt.year) - assert_equal(m, dt.month) - assert_equal(m, dt.mon) - assert_equal(d, dt.day) - - assert_equal(h, dt.hour) - assert_equal(mi,dt.min) - assert_equal(s, dt.sec) - end - - def test_set_values - dt = createDateTime() - y, m, d, h, mi, s = 1950, 12, 9, 8, 52, 30 - - dt.year = y - dt.month = m - dt.day = d - dt.hour = h - dt.min = mi - dt.sec = s - - assert_equal(y, dt.year) - assert_equal(m, dt.month) - assert_equal(m, dt.mon) - assert_equal(d, dt.day) - - assert_equal(h, dt.hour) - assert_equal(mi,dt.min) - assert_equal(s, dt.sec) - - dt.mon = 5 - assert_equal(5, dt.month) - assert_equal(5, dt.mon) - end - - def test_set_exception - dt = createDateTime() - - assert_raise(ArgumentError) { dt.year = 4.5 } - assert_nothing_raised(ArgumentError) { dt.year = -2000 } - - assert_raise(ArgumentError) { dt.month = 0 } - assert_raise(ArgumentError) { dt.month = 13 } - assert_nothing_raised(ArgumentError) { dt.month = 7 } - - assert_raise(ArgumentError) { dt.mon = 0 } - assert_raise(ArgumentError) { dt.mon = 13 } - assert_nothing_raised(ArgumentError) { dt.mon = 7 } - - assert_raise(ArgumentError) { dt.day = 0 } - assert_raise(ArgumentError) { dt.day = 32 } - assert_nothing_raised(ArgumentError) { dt.day = 16 } - - assert_raise(ArgumentError) { dt.hour = -1 } - assert_raise(ArgumentError) { dt.hour = 25 } - assert_nothing_raised(ArgumentError) { dt.hour = 12 } - - assert_raise(ArgumentError) { dt.min = -1 } - assert_raise(ArgumentError) { dt.min = 60 } - assert_nothing_raised(ArgumentError) { dt.min = 30 } - - assert_raise(ArgumentError) { dt.sec = -1 } - assert_raise(ArgumentError) { dt.sec = 60 } - assert_nothing_raised(ArgumentError) { dt.sec = 30 } - end - - def test_to_a - y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5 - dt = XMLRPC::DateTime.new(y, m, d, h, mi, s) - a = dt.to_a - - assert_instance_of(Array, a) - assert_equal(6, a.size, "Returned array has wrong size") - - assert_equal(y, a[0]) - assert_equal(m, a[1]) - assert_equal(d, a[2]) - assert_equal(h, a[3]) - assert_equal(mi, a[4]) - assert_equal(s, a[5]) - end - - def test_to_time1 - y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5 - dt = XMLRPC::DateTime.new(y, m, d, h, mi, s) - time = dt.to_time - - assert_not_nil(time) - - assert_equal(y, time.year) - assert_equal(m, time.month) - assert_equal(d, time.day) - assert_equal(h, time.hour) - assert_equal(mi, time.min) - assert_equal(s, time.sec) - end - - def test_to_time2 - dt = createDateTime() - dt.year = 1969 - - assert_nil(dt.to_time) - end - - def test_to_date1 - y, m, d, h, mi, s = 1970, 3, 24, 12, 0, 5 - dt = XMLRPC::DateTime.new(y, m, d, h, mi, s) - date = dt.to_date - - assert_equal(y, date.year) - assert_equal(m, date.month) - assert_equal(d, date.day) - end - - def test_to_date2 - dt = createDateTime() - dt.year = 666 - - assert_equal(666, dt.to_date.year) - end - - - def createDateTime - XMLRPC::DateTime.new(1970, 3, 24, 12, 0, 5) - end - -end -end diff --git a/test/xmlrpc/test_features.rb b/test/xmlrpc/test_features.rb deleted file mode 100644 index ea97ab8a09..0000000000 --- a/test/xmlrpc/test_features.rb +++ /dev/null @@ -1,51 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require "xmlrpc/create" -require "xmlrpc/parser" -require "xmlrpc/config" - -module TestXMLRPC -class Test_Features < Test::Unit::TestCase - - def setup - @params = [nil, {"test" => nil}, [nil, 1, nil]] - end - - def test_nil_create - XMLRPC::XMLWriter.each_installed_writer do |writer| - c = XMLRPC::Create.new(writer) - - XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)} - XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, false) - assert_raise(RuntimeError) { c.methodCall("test", *@params) } - - XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)} - XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true) - assert_nothing_raised { c.methodCall("test", *@params) } - end - end - - def test_nil_parse - XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_CREATE)} - XMLRPC::Config.const_set(:ENABLE_NIL_CREATE, true) - - XMLRPC::XMLWriter.each_installed_writer do |writer| - c = XMLRPC::Create.new(writer) - str = c.methodCall("test", *@params) - XMLRPC::XMLParser.each_installed_parser do |parser| - para = nil - - XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)} - XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, false) - assert_raise(RuntimeError) { para = parser.parseMethodCall(str) } - - XMLRPC::Config.module_eval {remove_const(:ENABLE_NIL_PARSER)} - XMLRPC::Config.const_set(:ENABLE_NIL_PARSER, true) - assert_nothing_raised { para = parser.parseMethodCall(str) } - assert_equal(para[1], @params) - end - end - end - -end -end diff --git a/test/xmlrpc/test_marshal.rb b/test/xmlrpc/test_marshal.rb deleted file mode 100644 index 251f9f6f29..0000000000 --- a/test/xmlrpc/test_marshal.rb +++ /dev/null @@ -1,111 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require "xmlrpc/marshal" - -module TestXMLRPC -class Test_Marshal < Test::Unit::TestCase - # for test_parser_values - class Person - include XMLRPC::Marshallable - attr_reader :name - def initialize(name) - @name = name - end - end - - - def test1_dump_response - assert_nothing_raised(NameError) { - XMLRPC::Marshal.dump_response('arg') - } - end - - def test1_dump_call - assert_nothing_raised(NameError) { - XMLRPC::Marshal.dump_call('methodName', 'arg') - } - end - - def test2_dump_load_response - value = [1, 2, 3, {"test" => true}, 3.4] - res = XMLRPC::Marshal.dump_response(value) - - assert_equal(value, XMLRPC::Marshal.load_response(res)) - end - - def test2_dump_load_call - methodName = "testMethod" - value = [1, 2, 3, {"test" => true}, 3.4] - exp = [methodName, [value, value]] - - res = XMLRPC::Marshal.dump_call(methodName, value, value) - - assert_equal(exp, XMLRPC::Marshal.load_call(res)) - end - - def test_parser_values - v1 = [ - 1, -7778, -(2**31), 2**31-1, # integers - 1.0, 0.0, -333.0, 2343434343.0, # floats - false, true, true, false, # booleans - "Hallo", "with < and >", "" # strings - ] - - v2 = [ - [v1, v1, v1], - {"a" => v1} - ] - - v3 = [ - XMLRPC::Base64.new("\001"*1000), # base64 - :aSymbol, :anotherSym # symbols (-> string) - ] - v3_exp = [ - "\001"*1000, - "aSymbol", "anotherSym" - ] - person = Person.new("Michael") - - XMLRPC::XMLParser.each_installed_parser do |parser| - m = XMLRPC::Marshal.new(parser) - - assert_equal( v1, m.load_response(m.dump_response(v1)) ) - assert_equal( v2, m.load_response(m.dump_response(v2)) ) - assert_equal( v3_exp, m.load_response(m.dump_response(v3)) ) - - pers = m.load_response(m.dump_response(person)) - - assert( pers.is_a?(Person) ) - assert( person.name == pers.name ) - end - - # missing, Date, Time, DateTime - # Struct - end - - def test_parser_invalid_values - values = [ - -1-(2**31), 2**31, - Float::INFINITY, -Float::INFINITY, Float::NAN - ] - XMLRPC::XMLParser.each_installed_parser do |parser| - m = XMLRPC::Marshal.new(parser) - - values.each do |v| - assert_raise(RuntimeError, "#{v} shouldn't be dumped, but dumped") \ - { m.dump_response(v) } - end - end - end - - def test_no_params_tag - # bug found by Idan Sofer - - expect = %{myMethod\n} - - str = XMLRPC::Marshal.dump_call("myMethod") - assert_equal(expect, str) - end - -end -end diff --git a/test/xmlrpc/test_parser.rb b/test/xmlrpc/test_parser.rb deleted file mode 100644 index 880044284c..0000000000 --- a/test/xmlrpc/test_parser.rb +++ /dev/null @@ -1,94 +0,0 @@ -# frozen_string_literal: false -require 'test/unit' -require 'xmlrpc/datetime' -require "xmlrpc/parser" -require 'yaml' - -module TestXMLRPC -module GenericParserTest - def datafile(base) - File.join(File.dirname(__FILE__), "data", base) - end - - def load_data(name) - [File.read(datafile(name) + ".xml"), YAML.load(File.read(datafile(name) + ".expected"))] - end - - def setup - @xml1, @expected1 = load_data('xml1') - @xml2, @expected2 = load_data('bug_covert') - @xml3, @expected3 = load_data('bug_bool') - @xml4, @expected4 = load_data('value') - - @cdata_xml, @cdata_expected = load_data('bug_cdata') - - @datetime_xml = File.read(datafile('datetime_iso8601.xml')) - @datetime_expected = XMLRPC::DateTime.new(2004, 11, 5, 1, 15, 23) - - @fault_doc = File.read(datafile('fault.xml')) - end - - # test parseMethodResponse -------------------------------------------------- - - def test_parseMethodResponse1 - assert_equal(@expected1, @p.parseMethodResponse(@xml1)) - end - - def test_parseMethodResponse2 - assert_equal(@expected2, @p.parseMethodResponse(@xml2)) - end - - def test_parseMethodResponse3 - assert_equal(@expected3, @p.parseMethodResponse(@xml3)) - end - - def test_cdata - assert_equal(@cdata_expected, @p.parseMethodResponse(@cdata_xml)) - end - - def test_dateTime - assert_equal(@datetime_expected, @p.parseMethodResponse(@datetime_xml)[1]) - end - - # test parseMethodCall ------------------------------------------------------ - - def test_parseMethodCall - assert_equal(@expected4, @p.parseMethodCall(@xml4)) - end - - # test fault ---------------------------------------------------------------- - - def test_fault - flag, fault = @p.parseMethodResponse(@fault_doc) - assert_equal(flag, false) - unless fault.is_a? XMLRPC::FaultException - assert(false, "must be an instance of class XMLRPC::FaultException") - end - assert_equal(fault.faultCode, 4) - assert_equal(fault.faultString, "an error message") - end - - def test_fault_message - fault = XMLRPC::FaultException.new(1234, 'an error message') - assert_equal('an error message', fault.to_s) - assert_equal('#', fault.inspect) - end -end - -# create test class for each installed parser -XMLRPC::XMLParser.each_installed_parser do |parser| - klass = parser.class - name = klass.to_s.split("::").last - - eval %{ - class Test_#{name} < Test::Unit::TestCase - include GenericParserTest - - def setup - super - @p = #{klass}.new - end - end - } -end -end diff --git a/test/xmlrpc/test_webrick_server.rb b/test/xmlrpc/test_webrick_server.rb deleted file mode 100644 index 268a01382d..0000000000 --- a/test/xmlrpc/test_webrick_server.rb +++ /dev/null @@ -1,136 +0,0 @@ -# coding: utf-8 -# frozen_string_literal: false - -require 'test/unit' -require 'webrick' -require_relative 'webrick_testing' -require "xmlrpc/server" -require 'xmlrpc/client' -require 'logger' - -module TestXMLRPC -class Test_Webrick < Test::Unit::TestCase - include WEBrick_Testing - - def create_servlet(server) - s = XMLRPC::WEBrickServlet.new - - basic_auth = WEBrick::HTTPAuth::BasicAuth.new( - :Realm => 'auth', - :UserDB => WEBrick::HTTPAuth::Htpasswd.new(File.expand_path('./htpasswd', File.dirname(__FILE__))), - :Logger => server.logger, - ) - - class << s; self end.send(:define_method, :service) {|req, res| - basic_auth.authenticate(req, res) - super(req, res) - } - - s.add_handler("test.add") do |a,b| - a + b - end - - s.add_handler("test.div") do |a,b| - if b == 0 - raise XMLRPC::FaultException.new(1, "division by zero") - else - a / b - end - end - - s.set_default_handler do |name, *args| - raise XMLRPC::FaultException.new(-99, "Method #{name} missing" + - " or wrong number of parameters!") - end - - s.add_introspection - - return s - end - - def setup_http_server_option(use_ssl) - option = { - :BindAddress => "localhost", - :Port => 0, - :SSLEnable => use_ssl, - } - if use_ssl - require 'webrick/https' - option.update( - :SSLVerifyClient => ::OpenSSL::SSL::VERIFY_NONE, - :SSLCertName => [] - ) - end - - option - end - - def test_client_server - # NOTE: I don't enable SSL testing as this hangs - [false].each do |use_ssl| - option = setup_http_server_option(use_ssl) - with_server(option, method(:create_servlet)) {|addr| - @s = XMLRPC::Client.new3(:host => addr.ip_address, :port => addr.ip_port, :use_ssl => use_ssl) - @s.user = 'admin' - @s.password = 'admin' - silent do - do_test - end - @s.http.finish - @s = XMLRPC::Client.new3(:host => addr.ip_address, :port => addr.ip_port, :use_ssl => use_ssl) - @s.user = '01234567890123456789012345678901234567890123456789012345678901234567890123456789' - @s.password = 'guest' - silent do - do_test - end - @s.http.finish - } - end - end - - def silent - begin - back, $VERBOSE = $VERBOSE, nil - yield - ensure - $VERBOSE = back - end - end - - def do_test - # simple call - assert_equal 9, @s.call('test.add', 4, 5) - - # fault exception - assert_raise(XMLRPC::FaultException) { @s.call('test.div', 1, 0) } - - # fault exception via call2 - ok, param = @s.call2('test.div', 1, 0) - assert_equal false, ok - assert_instance_of XMLRPC::FaultException, param - assert_equal 1, param.faultCode - assert_equal 'division by zero', param.faultString - - # call2 without fault exception - ok, param = @s.call2('test.div', 10, 5) - assert_equal true, ok - assert_equal param, 2 - - # introspection - assert_equal ["test.add", "test.div", "system.listMethods", "system.methodSignature", "system.methodHelp"], @s.call("system.listMethods") - - # default handler (missing handler) - ok, param = @s.call2('test.nonexisting') - assert_equal false, ok - assert_equal(-99, param.faultCode) - - # default handler (wrong number of arguments) - ok, param = @s.call2('test.add', 1, 2, 3) - assert_equal false, ok - assert_equal(-99, param.faultCode) - - # multibyte characters - assert_equal "あいうえおかきくけこ", @s.call('test.add', "あいうえお", "かきくけこ") - end -end -end diff --git a/test/xmlrpc/webrick_testing.rb b/test/xmlrpc/webrick_testing.rb deleted file mode 100644 index 7a3325df3c..0000000000 --- a/test/xmlrpc/webrick_testing.rb +++ /dev/null @@ -1,61 +0,0 @@ -# frozen_string_literal: false -require 'timeout' - -module TestXMLRPC -module WEBrick_Testing - def teardown - WEBrick::Utils::TimeoutHandler.terminate - super - end - - def start_server(logger, config={}) - raise "already started" if defined?(@__server) && @__server - @__started = false - - @__server = WEBrick::HTTPServer.new( - { - :BindAddress => "localhost", - :Logger => logger, - :AccessLog => [], - }.update(config)) - yield @__server - @__started = true - - addr = @__server.listeners.first.connect_address - - @__server_thread = Thread.new { - begin - @__server.start - rescue IOError => e - assert_match(/closed/, e.message) - ensure - @__started = false - end - } - - addr - end - - def with_server(config, servlet) - log = [] - logger = WEBrick::Log.new(log, WEBrick::BasicLog::WARN) - addr = start_server(logger, config) {|w| - servlet = servlet.call(w) if servlet.respond_to? :call - w.mount('/RPC2', servlet) - } - client_thread = Thread.new { - begin - yield addr - ensure - @__server.shutdown - end - } - server_thread = Thread.new { - @__server_thread.join - @__server = nil - assert_equal([], log) - } - assert_join_threads([client_thread, server_thread]) - end -end -end -- cgit v1.2.3