Git Product home page Git Product logo

xmlrpc's Introduction

XMLRPC

Build Status

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.

Installation

Add this line to your application's Gemfile:

gem 'xmlrpc'

And then execute:

$ bundle

Or install it yourself as:

$ gem install xmlrpc

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

Development

After checking out the repo, run bin/setup to install dependencies. Then, run rake test to run the tests. You can also run bin/console for an interactive prompt that will allow you to experiment.

To install this gem onto your local machine, run bundle exec rake install. To release a new version, update the version number in version.rb, and then run bundle exec rake release, which will create a git tag for the version, push git commits and tags, and push the .gem file to rubygems.org.

Contributing

Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/xmlrpc.

License

Released under the same term of license as Ruby.

xmlrpc's People

Contributors

dependabot[bot] avatar herwinw avatar hsbt avatar junaruga avatar kou avatar nobu avatar olleolleolle avatar ooooooo-q avatar pwnall avatar qnet-herwin avatar scottserok avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xmlrpc's Issues

IPv6

Hi - I can't seem to get IPv6 working.
Something changed when I updated my gems (not ruby) and now the URI Parsing isn't working with the bracket notation
If I do

Net::HTTP.new('::', 8080).start
=> #<Net::HTTP :::8080 open=true>

The socket is opened and the connection works to an XMLRPC server
If instead I do

XMLRPC::Client.new('[::]', '/RPC2', 8080).call('system.listMethods')
home/xxx/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:227:in `getaddrinfo': Failed to open TCP connection to [::]:8080 (getaddrinfo: Name or service not known) (SocketError)
/home/xxx/.rbenv/versions/3.1.0/lib/ruby/3.1.0/socket.rb:227:in `getaddrinfo': getaddrinfo: Name or service not known (SocketError)

I get this exception, which means the [::] IPv6 ip is being interpreted as a DNS hostname (the brackets must be trimmed)

If I monkey-patch XMLRPC::Client.net_http like this to trim the brackets manually

module XMLRPC
  class Client
    def net_http(host, port, proxy_host, proxy_port)
      Net::HTTP.new host.tr('[]', ''), port, proxy_host, proxy_port
    end
  end
end

Then the Net::HTTP instance is created correctly and the connection can be opened

XMLRPC::Client.new('[::]', '/path', 8080)
=> 
#<XMLRPC::Client:0x00007fd9e1098a68
 @auth=nil,
 @cookie=nil,
 @create=nil,
 @host="[::]",
 @http=#<Net::HTTP [::]:8080 open=false>,
 @http_header_extra=nil,
 @http_last_response=nil,
 @parser=nil,
 @password=nil,
 @path="/path",
 @port=8080,
 @proxy_host=nil,
 @proxy_port=nil,
 @timeout=30,
 @use_ssl=false,
 @user=nil>

But then when I try to call the client

XMLRPC::Client.new('[::]', '/path', 8080).call('system.listMethods')
/home/xxxx/.rbenv/versions/3.1.0/lib/ruby/3.1.0/uri/rfc3986_parser.rb:67:in `split': bad URI(is not URI?): "http://::/path" (URI::InvalidURIError)

I get an Invalid URI Error.

I can't seem to find the call point where a URI is built in call yet. Will try to monkey patch that to see if it works temporarily.

I have a feeling this is related to the age old bug here https://bugs.ruby-lang.org/issues/3788

Define open_timeout and read_timeout independently

Hi, is there any reason why we can't define open_timeout and read_timeout independently?

I would be happy to implement it; I think the following code would be enough:

    def open_timeout=(new_timeout)
      @http.open_timeout = new_timeout
    end

    def read_timeout=(new_timeout)
      @http.read_timeout = new_timeout
    end

DigestAuth

How can i make a xmlrpc request with DigestAuth, i have tried adding http_header_extra but if some one can help me creating a request with DigestAuth that would be really great.

Integrate xmlrpc-streaming gem

There is a very old gem on https://github.com/washu/xmlrpc-streaming, with the following feature set:

  • Base64 now accepts an IO object to its constructor
  • The XMLRPC request will now be streamed to the server. This will be a little faster and generate much less garbage. It should also fix issues where large Base64 objects sent to the server can cause out of memory errors
  • Base64 now has a to_io methods that will give access to the underlying data as a IO object note: this is the raw data.
  • set_writer will be ignored if this module has been loaded.
  • the parser will now try the following, nokogiri, libxml and finally fallback to REXML
  • This module can be used completely transparently, just require the lib and nothing else needs done

The current release of this Gem is 0.1.0, and it hasn't been updated since 2011. The xmlrpc gem has a parser using libxml nowadays, but these two differ. I have no idea of the gem still works with the current release of xmlrpc.

It would be nice to have the functionality in the addon merged into the base release. I'm open to making the changes, but first I want to be sure this would be accepted, and that merging this foreign gem is even allowed (notify for @washu)

Possibility for calling method on nil in client

The method do_rpc in the client has the following check for content-length, currently line 529-532:

# data is set to resp.body a few lines earlier

expected = resp["Content-Length"] || "<unknown>"
if data.nil? or data.bytesize == 0
  raise "Wrong size. Was #{data.bytesize}, should be #{expected}"
end

If data equals nil, this would try to call bytesize on it, resulting in a NoMethodError. This makes the error very confusing.

Since data.nil? is a scenario that should not happen, and is pretty much distinct from an invalid content-length, I guess the best option would be to add a specific check for data.nil? after the assignment of data, throw a specific error if that happens, and the rest of the code can safely assume data is not nil.

XMLRPC::Server port attribute

Right now Server doesn't really support port=0.
To WEBrick port=0 indicates that it should pick a port automatically. This still works with XMLRPC::Server as the argument is simply passed along. Currently there is no way to get the automatically determined port though. So, you can tell the server to pick a port but then you don't know which port it picked ๐Ÿ™„
It would be lovely if Server could get a simple forwarded attribute to either read webrick's config[:Port] or to config as a whole.

For unit testing purposes I do not care about the actual port used, I do however care that this port is dynamically picked so it doesn't conflict with concurrently running tests and/or other services.

s = XMLRPC::Server.new(0)
port = s.port # @server.config.fetch(:Port)
url = "http://localhost:#{port}"
test_handlers(url)

Suggestion: Disable ENABLE_MARSHALLING by default

Given the plethora of cases about possible RCE vulnerabilities that have led to the 0.3.3 release, I would like to argue that the default object marshalling is incorrect.

Beside the security related issues, there is also the issue that XML-RPC is a language agnostic protocol, and the Ruby object marshalling is a Ruby only extension. It would not make any sense to serialize a Ruby object when the server is running Perl, Python or any other language that is not Ruby. The other XML-RPC extensions (8 byte integers, nil serialization, nil deserialization) are disabled by default as well.

Of course, I might be totally wrong here. Are there any people who actually use the object serialization of this gem?

Easier way to serialize objects over XMLRPC

Currently there is no simple way to transport a non-default object over XMLRPC with this lib.

Contrived example

We have a Money class, with 3 values: currency (like Dollar, Euro, Yen), whole and cents. With Money.new(:dollar, 13, 37) we'd create a new object to represent $ 13.37.

Current ways to transfer this over XMLRPC:

Convert it to a more basic structure

We could convert this object manually to the String "$ 13.37" and transfer this. This means manual intervention on every XMLRPC call.

Use XMLRPC::Marshallable

This would result in marshalled objects that look pretty specific to Ruby, which would stop interoperability with other languages. This same problem arises when using Marshall or YAML to dump the structure.

Use Structs

There is logic to write structs over XMLRPC, but this loses the class name. If we had an abstract Money class that didn't save the currency, but instead had a Dollar, Euro and Yen subclass (like I said: contrived example), everything would be marshalled as the value only, without the currency. It basicly converts a Struct to a Hash

Override XMLRPC::Create#wrong_type

We could include duck typing here, but that feels cumbersome

Proposed solutions

I think there are two possible options to improve this:

Duck typing on to_xmlrpc

Allow classes to implement a #to_xmlrpc method, call that if applicable and use that converted value. This is comparable with things like #to_json. A point of discussion here is we'd have to have the method create an XMLRPC element, or if it just enough to create a String, Integer, Hash or whatever and feed that back into conv2value

Register classes in XMLRPC::Create

A different solution would be to register a class and conversion block in XMLRPC::Create, syntax would be a bit like this:

XMLRPC::Create.register_serializer(Money) { |obj| "MONEY: #{obj}" }

Where the exact value would depend upon agreements between client and server

Content-Type is not text/xml leads to error

If the responses content-type is not text/xml, the client.rb prints out an error, even if the http_header_field is set to another content-type and the request was send correctly.

Wrong content-type (received 'application/xml' but expected 'text/xml')

The reason for this is client.rb line 519, where you will get an error in any case if the content type is not equal text/html

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

Rename binaries

Would you mind to rename the binaries shipped by XMLRPC gem? Both console as well as setup are so generic, that there is not obvious relation to XMLRPC and what is worse, they will certainly conflict with other binaries. These are conflicting binaries on my Fedora Rawhide:

# dnf whatprovides /usr/bin/console
Last metadata expiration check: 1:16:11 ago on Fri May 27 16:14:22 2016.
conserver-client-8.2.1-3.fc24.x86_64 : Serial console client
Repo        : rawhide
# dnf whatprovides /usr/bin/setup
Last metadata expiration check: 1:16:18 ago on Fri May 27 16:14:22 2016.
setuptool-1.19.11-11.fc24.x86_64 : A text mode system configuration tool
Repo        : @System

setuptool-1.19.11-11.fc24.x86_64 : A text mode system configuration tool
Repo        : rawhide

Bring support for self-signed SSL certificates

Bring issue is tied to fog/fog-xenserver#68 fog is the Ruby library for starting/stopping/and controlling VMs. XenServer, the Citrix product, has a plugin called fog-xenserver. It uses ruby/xmlrpc. It fails to connect to the new instance of XenServer, because its certificate is self-signed.

RIght now we have no way to letting XMLRPC know that the cert would be self-signed. My suggestion is to use following logic, which will change ruby/xmlrpc minimally:

use_ssl == true: enable SSL, normal SSL certificate validation
use_ssl == false: no SSL
use_ssl == -1: enable SSL, patched workaround for ignoring exception for self-signed cert.

More elegant way would be to just add verify_mode and for each VERIFY_NONE, VERIFY_PEER, VERIFY_CLIENT_ONCE, VERIFY_FAIL_IF_NO_PEER_CERT have "none", "peer", "client_once", "fail_if_no_peer_cert".

@plribeiro3000 Let's discuss changes here, so that we can decide what's the best way to enable self-signed certs.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.