Singing xmlrpc with Ruby and Sinatra

I was fighting Sinatra in order to make it an xmlrpc server. The big problem is that the xmlrpc library that arrive with Ruby -> well it sucks big time.

The client actually really nice, but the server really sucks. So, I started fighting the XMLRPC, and Sinatra did not like some of my work, and did not want to go to stage to perform, and I needed to talk with it's manager🙂

At the end I found out why Sinatra and XMLRPC server does not like each other, and I was able to make Sinatra work with XMLRPC server at the end. The problem of course is the XMLRPC, and Sinatra actually a fine singer (so take off the Mafia from me now ok ?).

So how we can make Sinatra find dity and perform with XMLRPC as a server ?

Here is a Proof of concept for working with the two of them (writing it without testing the PoC):

#!/usr/bin/env ruby
require 'rubygems'
require 'sinatra'
require 'uri'
require 'xmlrpc/server'
require 'xmlrpc/marshal'
require 'xmlrpc/parser'
require 'xmlrpc/create'
require 'xmlrpc/config'
require 'xmlrpc/utils'

module MyModule
  class Application < Sinatra::Base
    def initialize(app=nil)
      super                        # we are inheriting stuff from older constructor
      ...                          # fill in the missing stuff you need for your app
      @rpc = XMLRPC::CGIServer.new # We are using general server rather then actual server
      # The line bellow is a MUST for make it work properly, add some dummy call
      # or if we have only one call, it will also work for us
      @rpc.set_default_handler do | dummy |
        dummy
      end # @rpc.set_default_handler do | dummy |

      # <?xml version="1.0"?>
      # <methodCall>
      #   <methodName>ngx1.call_init</methodName>
      #   <params>
      #     <param>
      #       <value>
      #          <struct>
      #             <member>
      #               <name>x</name>
      #               <value><int>10</int></value>
      #             </member>
      #             <member>
      #               <name>y</name>
      #               <value><int>10</int></value>
      #             </member>
      #          </struct>
      #       </value>
      #     </param>
      #   </params>
      # </methodCall>
      @rpc.add_handler('sum') do | x, y | # names of params must be equal to the rpc names
         x + y   # sending the result as xmlrpc
      end # @rpc.add_handler('sum')

    end # initialize(app=nil)

    get '/' do
      throw :halt, [400, 'XML-RPC server accepts POST requests only.']
    end # get '/' do

     post '/' do
       throw :halt, [400, 'bad request type'] unless request.content_type =~ %r|text/xml|
       headers 'Content-Type' => 'text/xml'
       begin
         @responce = @rpc.process(request.body.read) # lets read the content from the client and proccess it
       rescue RuntimeError
         header 'Content-Type' => 'text/plain'
         throw :halt, [400, 'bad request type']
       end # rescue
     end # post '/' do

   end # Application < Sinatra::Base
end # MyModule

And now Sinatra can sing again "New York New York" -> "If i can make it there, I'll make it anywhere"

כתיבת תגובה

הזינו את פרטיכם בטופס, או לחצו על אחד מהאייקונים כדי להשתמש בחשבון קיים:

הלוגו של WordPress.com

אתה מגיב באמצעות חשבון WordPress.com שלך. לצאת מהמערכת / לשנות )

תמונת Twitter

אתה מגיב באמצעות חשבון Twitter שלך. לצאת מהמערכת / לשנות )

תמונת Facebook

אתה מגיב באמצעות חשבון Facebook שלך. לצאת מהמערכת / לשנות )

תמונת גוגל פלוס

אתה מגיב באמצעות חשבון Google+ שלך. לצאת מהמערכת / לשנות )

מתחבר ל-%s