paidapi/paid-ruby

View on GitHub
lib/paid/requester.rb

Summary

Maintainability
A
2 hrs
Test Coverage
module Paid
  module Requester

    def self.request(method, url, params, headers)
      method = method.to_sym
      url, params = prepare_params(url, params, method)
      request_opts = {
        :method => method,
        :url => url,
        :headers => headers,
        :payload => params,

        :verify_ssl => false,
        :open_timeout => 30,
        :timeout => 60
      }

      execute_request(request_opts)
    end

    def self.execute_request(opts)
      RestClient::Request.execute(opts)
    end

    def self.get(url, params, headers)
      self.request(:get, url, params, headers)
    end

    def self.delete(url, params, headers)
      self.request(:delete, url, params, headers)
    end

    def self.put(url, params, headers)
      self.request(:put, url, params, headers)
    end

    def self.post(url, params, headers)
      self.request(:post, url, params, headers)
    end

    def self.prepare_params(url, params, method)
      if [:get, :head, :delete].include?(method)
        unless params.empty?
          url += URI.parse(url).query ? '&' : '?' + query_string(params)
        end
        params = nil
      else
        if !RestClient::Payload.has_file?(params)
          params = query_string(params)
        end
      end
      [url, params]
    end

    def self.query_string(params)
      params ||= {}
      if params.any?
        query_array(params).join('&')
      else
        ""
      end
    end

    # Three major use cases (and nesting of them needs to be supported):
    #   { :a => { :b => "bvalue" } }  => ["a[b]=bvalue"]
    #   { :a => [1, 2] }           => ["a[]=1", "a[]=2"]
    #   { :a => "value" }          => ["a=value"]
    def self.query_array(params, key_prefix=nil)
      ret = []
      params.each do |key, value|
        if params.is_a?(Array)
          value = key
          key = ''
        end
        key_suffix = escape(key)
        full_key = key_prefix ? "#{key_prefix}[#{key_suffix}]" : key_suffix

        if value.is_a?(Hash) || value.is_a?(Array)
          # Handles the following cases:
          #   { :a => { :b => "bvalue" } }  => ["a[b]=bvalue"]
          #   { :a => [1, 2] }           => ["a[]=1", "a[]=2"]
          ret += query_array(value, full_key)
        else
          # Handles the base case with just key and value:
          #   { :a => "value" } => ["a=value"]
          ret << "#{full_key}=#{escape(value)}"
        end
      end
      ret
    end

    def self.escape(val)
      CGI::escape(val.to_s)
    end

  end
end