class Riddl::Client::Resource

}}}

Attributes

rpath[R]

Public Class Methods

new(base,wrapper,path,options) click to toggle source
# File lib/ruby/riddl/client.rb, line 137
def initialize(base,wrapper,path,options) #{{{
  @base = base
  @wrapper = wrapper
  @rpath = "/#{path}".gsub(/\/+/,'/')
  @options = options
  @path = if @wrapper.nil?
    @rpath
  else
    @path = @wrapper.paths.find{ |e| e[1] =~ @rpath }
    raise PathError, 'Path not found.' if @path.nil?
    @path[0]
  end
  @rpath = @rpath == '/' ? '' : @rpath
end

Public Instance Methods

delete(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 197
def delete(parameters = []) #{{{
  exec_request('DELETE',parameters,false)
end
get(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 169
def get(parameters = []) #{{{
  exec_request('GET',parameters,false)
end
patch(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 190
def patch(parameters = []) #{{{
  exec_request('PATCH',parameters,false)
end
post(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 176
def post(parameters = []) #{{{
  exec_request('POST',parameters,false)
end
put(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 183
def put(parameters = []) #{{{
  exec_request('PUT',parameters,false)
end
request(what) click to toggle source
# File lib/ruby/riddl/client.rb, line 204
def request(what) #{{{
  priv_request(what,false)
end
simulate_delete(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 200
def simulate_delete(parameters = []) #{{{
  exec_request('DELETE',parameters,true)
end
simulate_get(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 172
def simulate_get(parameters = []) #{{{
  exec_request('GET',parameters,true)
end
simulate_patch(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 193
def simulate_patch(parameters = []) #{{{
  exec_request('PATCH',parameters,true)
end
simulate_post(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 179
def simulate_post(parameters = []) #{{{
  exec_request('POST',parameters,true)
end
simulate_put(parameters = []) click to toggle source
# File lib/ruby/riddl/client.rb, line 186
def simulate_put(parameters = []) #{{{
  exec_request('PUT',parameters,true)
end
simulate_request(what) click to toggle source
# File lib/ruby/riddl/client.rb, line 207
def simulate_request(what) #{{{
  priv_request(what,true)
end
ws(&blk) click to toggle source
# File lib/ruby/riddl/client.rb, line 153
def ws(&blk) #{{{
  EM.run {
    url = (@base + @rpath).sub(/^http/,'ws')
    url = url.sub(/:\/\/localhost/,'://127.0.0.1')
    conn = Faye::WebSocket::Client.new(url)

    if @options[:debug]
      conn.on :error do |e|
        @options[:debug].puts "WS ERROR: #{e}"
      end
    end

    blk.call(conn)
  }
end

Private Instance Methods

exec_request(riddl_method,parameters,simulate) click to toggle source
# File lib/ruby/riddl/client.rb, line 266
def exec_request(riddl_method,parameters,simulate) #{{{
  parameters = [ parameters ] unless parameters.is_a? Array
  (URI.parse(@base)&.query || '').split(/[#{D}] */n).each do |p|
    k, v = Riddl::Protocols::Utils::unescape(p).split('=', 2)
    parameters << Parameter::Simple.new(k,v,:query)
  end
  parameters = parameters.dup
  headers = extract_headers(parameters)
  options = extract_options(parameters)
  role = nil

  unless @wrapper.nil?
    role = @wrapper.role(@path)
    if Riddl::Roles::roles[role]
      Riddl::Roles::roles[role]::before(@base + @rpath,riddl_method.downcase,parameters,headers,options) if Riddl::Roles::roles[role].respond_to?(:before)
    end
    riddl_message = @wrapper.io_messages(@path,riddl_method.downcase,parameters,headers)
    if riddl_message.nil?
      raise InputError, "Not a valid input to service."
    end
  end

  qparams = extract_qparams(parameters,riddl_method.downcase)

  response = nil
  if @wrapper.nil? || @wrapper.description? || (@wrapper.declaration? && !@base.nil?)
    status, response, response_headers = make_request(@base + @rpath,riddl_method,parameters,headers,qparams,simulate,riddl_message && riddl_message.out ? true : false)
    return response if simulate
    if !@wrapper.nil? && status >= 200 && status < 300
      unless @wrapper.check_message(response,response_headers,riddl_message.out)
        raise OutputError, "Not a valid output from service."
      end
    end
  elsif !@wrapper.nil? && @base.nil? && @wrapper.declaration?
    headers['RIDDL-DECLARATION-PATH'] = @rpath
    if !riddl_message.route?
      status, response, response_headers = make_request(riddl_message.interface.real_url(@rpath,@base),riddl_method,parameters,headers,qparams,simulate,riddl_message && riddl_message.out ? true : false)
      return response if simulate
      if status >= 200 && status < 300
        unless @wrapper.check_message(response,response_headers,riddl_message.out)
          raise OutputError, "Not a valid output from service."
        end
      end
    else
      tp = parameters
      th = headers
      tq = qparams
      riddl_message.route.each do |m|
        if m == riddl_message.route.last
          status, response, response_headers = make_request(m.interface.real_url(@rpath,@base),riddl_method,tp,th,tq,simulate,riddl_message && riddl_message.out ? true : false)
        else
          status, response, response_headers = make_request(m.interface.real_url(@rpath,@base),riddl_method,tp,th,tq,simulate,true)
        end
        return response if simulate
        if status < 200 || status >= 300 || !@wrapper.check_message(response,response_headers,m.out)
          raise OutputError, "Not a valid output from service."
        end
        unless m == riddl_message.route.last
          tp = response
          th = extract_headers(response) # TODO extract relvant headers from res (get from m.out)
          tq = extract_qparams(response,riddl_method.downcase)
        end
      end
    end
  else
    raise OutputError, "Impossible Error :-)"
  end
  unless role.nil?
    if Riddl::Roles::roles[role]
      response = Riddl::Roles::roles[role]::after(@base + @rpath,riddl_method.downcase,status,response,response_headers,options) if Riddl::Roles::roles[role].respond_to?(:after)
    end
  end
  return status, response, response_headers
end
extract_headers(parameters) click to toggle source
# File lib/ruby/riddl/client.rb, line 233
def extract_headers(parameters) #{{{
  headers = {}
  parameters.delete_if do |p|
    if p.class == Riddl::Header
      headers[p.name.upcase] = "#{p.value}"
      true
    else
      false
    end
  end
  headers
end
extract_options(parameters) click to toggle source
# File lib/ruby/riddl/client.rb, line 220
def extract_options(parameters) #{{{
  options = {}
  parameters.delete_if do |p|
    if p.class == Riddl::Option
      options[p.name] = "#{p.value}"
      true
    else
      false
    end
  end
  options
end
extract_qparams(parameters,method) click to toggle source
# File lib/ruby/riddl/client.rb, line 247
def extract_qparams(parameters,method) #{{{
  qparams = []
  starting = true
  parameters.delete_if do |p|
    if starting && p.class == Riddl::Parameter::Simple && method == 'get'
      p.type = :query
    end
    if p.class == Riddl::Parameter::Simple && p.type == :query
      qparams << Protocols::Utils::escape(p.name) + (p.value.nil? ? '' : '=' + Protocols::Utils::escape(p.value))
      true
    else
      starting = false
      false
    end
  end
  qparams
end
make_request(url,riddl_method,parameters,headers,qparams,simulate,ack) click to toggle source
# File lib/ruby/riddl/client.rb, line 342
def make_request(url,riddl_method,parameters,headers,qparams,simulate,ack) #{{{
  url = URI.parse(url)
  qs = qparams.join('&')
  if url.class == URI::HTTP || url.class == URI::HTTPS
    #{{{
    return Riddl::Client::SimulateRequest.new(riddl_method,url.path,parameters,headers,qs).simulate if simulate

    path = (url.path.strip == '' ? '/' : url.path)
    path += "?#{qs}" unless qs == ''
    uri = url.scheme + '://' + url.host + ':' + url.port.to_s + path

    tmp = Protocols::HTTP::Generator.new(parameters,headers).generate(:input)

    opts = {
      :method         => riddl_method,
      :headers        => headers,
      :body           => tmp.read,
      :ssl_verifypeer => false
      # :followlocation => true
    }
    if url.user && url.password
      opts[:username] = Protocols::Utils::unescape(url.user)
      opts[:password] = Protocols::Utils::unescape(url.password)
      opts[:httpauth] = :auto
    end
    if @options[:debug]
      opts[:verbose] = true ### sadly only to console, does not respect @options[:debug]
    end

    begin
      req = Typhoeus::Request.new(uri,opts)
      res = req.run

      response_headers = {}
      res.headers.each do |k,v|
        if v.nil?
          response_headers[k.name.upcase.gsub(/\-/,'_')] = v
        else
          response_headers[k.upcase.gsub(/\-/,'_')] = v
        end
      end

      if res.code.to_i == 302 || res.code.to_i == 301
        uri = response_headers['LOCATION']
      end
    end while res.code.to_i == 302 || res.code.to_i == 301

    bs = Parameter::Tempfile.new("RiddlBody")
    bs.write res.body
    bs.rewind

    response = Riddl::Protocols::HTTP::Parser.new(
      "",
      bs,
      response_headers['CONTENT_TYPE'],
      response_headers['CONTENT_LENGTH'].to_i != bs.length ? 0 : response_headers['CONTENT_LENGTH'], # because when gzip content length differs from bs length
      response_headers['CONTENT_DISPOSITION'],
      response_headers['CONTENT_ID'],
      response_headers['RIDDL_TYPE']
    ).params
    bs.close

    return res.code.to_i, response, response_headers
    #}}}
  else
    if @options[:custom_protocol]
      return @options[:custom_protocol].handle(url,riddl_method,parameters,headers,qs,simulate,ack)
    else
      path = (url.path.strip == '' ? '/' : url.path)
      uri = url + (qs.empty? ? '' : "?#{qs}")
      res = Typhoeus.get(uri)
      return (res.return_code == :ok ? 200 : 500), [Riddl::Parameter::Simple.new('result',res.body)], {}
    end
  end
  raise URIError, "not a valid URI (http, https, ... are accepted)"
end
priv_request(what,simulate) click to toggle source
# File lib/ruby/riddl/client.rb, line 210
def priv_request(what,simulate) #{{{
  if what.class == Hash && what.length == 1
    what.each do |method,parameters|
      return exec_request(method.to_s.upcase,parameters,simulate)
    end
  end
  raise ArgumentError, "Hash with ONE method => parameters pair required"
end