class Flexirest::Request

Attributes

body[RW]
forced_url[RW]
get_params[RW]
headers[RW]
method[RW]
object[RW]
original_url[RW]
path[RW]
post_params[RW]
retrying[RW]
url[RW]

Public Class Methods

new(method, object, params = {}) click to toggle source
# File lib/flexirest/request.rb, line 14
def initialize(method, object, params = {})
  @method                     = method
  @method[:options]           ||= {}
  @method[:options][:lazy]    ||= []
  @method[:options][:array]   ||= []
  @method[:options][:has_one] ||= {}
  @overridden_name            = @method[:options][:overridden_name]
  @object                     = object
  @response_delegate          = Flexirest::RequestDelegator.new(nil)
  @params                     = params
  @headers                    = HeadersList.new
  (@method[:options][:headers] || {}).each do |k,v|
    @headers[k] = v
  end
  @forced_url                 = nil
end

Public Instance Methods

api_auth_access_id() click to toggle source
# File lib/flexirest/request.rb, line 75
def api_auth_access_id
  ret = nil
  if object_is_class?
    ret = @object.api_auth_access_id
    ret = ret.call if ret.respond_to?(:call)
  else
    ret = @object.class.api_auth_access_id
    ret = ret.call(@object) if ret.respond_to?(:call)
  end
  ret
end
api_auth_options() click to toggle source
# File lib/flexirest/request.rb, line 99
def api_auth_options
  if object_is_class?
    @object.api_auth_options
  else
    @object.class.api_auth_options
  end
end
api_auth_secret_key() click to toggle source
# File lib/flexirest/request.rb, line 87
def api_auth_secret_key
  ret = nil
  if object_is_class?
    ret = @object.api_auth_secret_key
    ret = ret.call if ret.respond_to?(:call)
  else
    ret = @object.class.api_auth_secret_key
    ret = ret.call(@object) if ret.respond_to?(:call)
  end
  ret
end
append_get_parameters() click to toggle source
# File lib/flexirest/request.rb, line 441
def append_get_parameters
  if @get_params.any?
    if @method[:options][:params_encoder] == :flat
      @url += "?" + URI.encode_www_form(@get_params)
    else
      @url += "?" + @get_params.to_query
    end
  end
end
base_url() click to toggle source
# File lib/flexirest/request.rb, line 55
def base_url
  if object_is_class?
    url = @object.base_url
  else
    url = @object.class.base_url
  end
  if url.is_a?(Array)
    url = url.sample
  end
  url
end
basic_auth_digest() click to toggle source
# File lib/flexirest/request.rb, line 139
def basic_auth_digest
  Base64.strict_encode64("#{username}:#{password}")
end
call(explicit_parameters=nil) click to toggle source
# File lib/flexirest/request.rb, line 225
def call(explicit_parameters=nil)
  @instrumentation_name = "#{class_name}##{@method[:name]}"
  result = nil
  cached = nil
  ActiveSupport::Notifications.instrument("request_call.flexirest", :name => @instrumentation_name) do
    @explicit_parameters = explicit_parameters
    @body = nil
    prepare_params
    prepare_url
    fake = @method[:options][:fake]
    if fake.present?
      if fake.respond_to?(:call)
        fake = fake.call(self)
      elsif @object.respond_to?(fake)
        fake = @object.send(fake)
      elsif @object.class.respond_to?(fake)
        fake = @object.class.send(fake)
      elsif @object.new.respond_to?(fake)
        fake = @object.new.send(fake)
      elsif @object.class.new.respond_to?(fake)
        fake = @object.class.new.send(fake)
      end
      Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Faked response found"
      content_type = @method[:options][:fake_content_type] || "application/json"
      return handle_response(OpenStruct.new(status:200, body:fake, response_headers:{"X-ARC-Faked-Response" => "true", "Content-Type" => content_type}))
    end
    if object_is_class?
      callback_result = @object.send(:_callback_request, :before, @method[:name], self)
    else
      callback_result = @object.class.send(:_callback_request, :before, @method[:name], self)
    end
    if callback_result == false
      return false
    end

    append_get_parameters
    prepare_request_body
    self.original_url = self.url
    cached = original_object_class.read_cached_response(self)
    if cached && !cached.is_a?(String)
      if cached.expires && cached.expires > Time.now
        Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Absolutely cached copy found"
        return handle_cached_response(cached)
      elsif cached.etag.to_s != "" #present? isn't working for some reason
        Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Etag cached copy found with etag #{cached.etag}"
        etag = cached.etag
      end
    end

    response = (
      if proxy && proxy.is_a?(Class)
        proxy.handle(self) do |request|
          request.do_request(etag)
        end
      else
        do_request(etag)
      end
    )

    # This block is called immediately when this request is not inside a parallel request block.
    # Otherwise this callback is called after the parallel request block ends.
    response.on_complete do |response_env|
      if verbose?
        Flexirest::Logger.debug "  Response"
        Flexirest::Logger.debug "  << Status : #{response_env.status}"
        response_env.response_headers.each do |k,v|
          Flexirest::Logger.debug "  << #{k} : #{v}"
        end
        Flexirest::Logger.debug "  << Body:\n#{response_env.body}"
      end

      if object_is_class? && @object.record_response?
        @object.record_response(self.url, response_env)
      end

      begin
        if object_is_class?
          callback_result = @object.send(:_callback_request, :after, @method[:name], response_env)
        else
          callback_result = @object.class.send(:_callback_request, :after, @method[:name], response_env)
        end
      rescue Flexirest::CallbackRetryRequestException
        if self.retrying != true
          self.retrying = true
          return call()
        end
      end

      result = handle_response(response_env, cached)
      @response_delegate.__setobj__(result)
      original_object_class.write_cached_response(self, response_env, result) unless @method[:options][:skip_caching]
    end

    # If this was not a parallel request just return the original result
    return result if response.finished?
    # Otherwise return the delegate which will get set later once the call back is completed
    return @response_delegate
  end
end
class_name() click to toggle source
# File lib/flexirest/request.rb, line 39
def class_name
  if object_is_class?
    @object.name
  else
    @object.class.name
  end
end
delete?() click to toggle source
# File lib/flexirest/request.rb, line 221
def delete?
  http_method == :delete
end
do_request(etag) click to toggle source
# File lib/flexirest/request.rb, line 524
def do_request(etag)
  http_headers = {}
  http_headers["If-None-Match"] = etag if etag && !@method[:options][:skip_caching]
  http_headers["Accept"] = "application/hal+json, application/json;q=0.5"
  headers.each do |key,value|
    value = value.join(",") if value.is_a?(Array)
    http_headers[key] = value
  end
  if @method[:options][:url] || @forced_url
    @url = @method[:options][:url] || @method[:url]
    @url = @forced_url if @forced_url
    if connection = Flexirest::ConnectionManager.find_connection_for_url(@url)
      @url = @url.slice(connection.base_url.length, 255)
    else
      parts = @url.match(%r{^(https?://[a-z\d\.:-]+?)(/.*)}).to_a
      if (parts.empty?) # Not a full URL, so use hostname/protocol from existing base_url
        uri = URI.parse(base_url)
        @base_url = "#{uri.scheme}://#{uri.host}#{":#{uri.port}" if uri.port != 80 && uri.port != 443}"
        @url = "#{base_url}#{@url}".gsub(@base_url, "")
      else
        _, @base_url, @url = parts
      end
      if using_basic_auth? && model_class.basic_auth_method == :url
        inject_basic_auth_in_url(base_url)
      end
      connection = Flexirest::ConnectionManager.get_connection(base_url)
    end
  else
    parts = @url.match(%r{^(https?://[a-z\d\.:-]+?)(/.*)?$}).to_a
    if (parts.empty?) # Not a full URL, so use hostname/protocol from existing base_url
      uri = URI.parse(base_url)
      @base_url = "#{uri.scheme}://#{uri.host}#{":#{uri.port}" if uri.port != 80 && uri.port != 443}"
      @url = "#{base_url}#{@url}".gsub(@base_url, "")
      base_url = @base_url
    else
      base_url = parts[0]
    end
    if using_basic_auth? && model_class.basic_auth_method == :url
      inject_basic_auth_in_url(base_url)
    end
    connection = Flexirest::ConnectionManager.get_connection(base_url)
  end
  if @method[:options][:direct]
    Flexirest::Logger.info "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Requesting #{@url}"
  else
    Flexirest::Logger.info "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Requesting #{connection.base_url}#{@url}"
  end

  if verbose?
    Flexirest::Logger.debug "Flexirest Verbose Log:"
    Flexirest::Logger.debug "  Request"
    Flexirest::Logger.debug "  >> #{http_method.upcase} #{@url} HTTP/1.1"
    http_headers.each do |k,v|
      Flexirest::Logger.debug "  >> #{k} : #{v}"
    end
    Flexirest::Logger.debug "  >> Body:\n#{@body}"
  end

  request_options = {:headers => http_headers}
  if using_api_auth?
    request_options[:api_auth] = {
      :api_auth_access_id => api_auth_access_id,
      :api_auth_secret_key => api_auth_secret_key,
      :api_auth_options => api_auth_options
    }
  elsif using_basic_auth? && model_class.basic_auth_method == :header
    http_headers["Authorization"] = "Basic #{basic_auth_digest}"
  end
  if @method[:options][:timeout]
    request_options[:timeout] = @method[:options][:timeout]
  end

  case http_method
  when :get
    response = connection.get(@url, request_options)
  when :put
    response = connection.put(@url, @body, request_options)
  when :post
    response = connection.post(@url, @body, request_options)
  when :patch
    response = connection.patch(@url, @body, request_options)
  when :delete
    response = connection.delete(@url, @body, request_options)
  else
    raise InvalidRequestException.new("Invalid method #{http_method}")
  end

  response
end
get?() click to toggle source
# File lib/flexirest/request.rb, line 209
def get?
  http_method == :get
end
hal_response?() click to toggle source
# File lib/flexirest/request.rb, line 775
def hal_response?
  _, content_type = @response.response_headers.detect{|k,v| k.downcase == "content-type"}
  faked_response = @response.response_headers.detect{|k,v| k.downcase == "x-arc-faked-response"}
  if content_type && content_type.respond_to?(:each)
    content_type.each do |ct|
      return true if ct[%r{application\/hal\+json}i]
      return true if ct[%r{application\/json}i]
    end
    faked_response
  elsif content_type && (content_type[%r{application\/hal\+json}i] || content_type[%r{application\/json}i]) || faked_response
    true
  else
    false
  end
end
handle_cached_response(cached) click to toggle source
# File lib/flexirest/request.rb, line 614
def handle_cached_response(cached)
  if cached.result.is_a? Flexirest::ResultIterator
    cached.result
  else
    if object_is_class?
      cached.result
    else
      @object._copy_from(cached.result)
      @object
    end
  end
end
handle_response(response, cached = nil) click to toggle source
# File lib/flexirest/request.rb, line 627
def handle_response(response, cached = nil)
  @response = response
  status = @response.status || 200
  if @response.body.blank?
    @response.response_headers['Content-Type'] = "application/json"
    @response.body = "{}"
  end

  if cached && response.status == 304
    Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name}" +
      ' - Etag copy is the same as the server'
    return handle_cached_response(cached)
  end

  if (200..399).include?(status)
    if @method[:options][:plain]
      return @response = Flexirest::PlainResponse.from_response(@response)
    elsif is_json_response? || is_xml_response?
      if @response.respond_to?(:proxied) && @response.proxied
        Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Response was proxied, unable to determine size"
      else
        Flexirest::Logger.debug "  \033[1;4;32m#{Flexirest.name}\033[0m #{@instrumentation_name} - Response received #{@response.body.size} bytes"
      end
      result = generate_new_object(ignore_root: ignore_root, ignore_xml_root: @method[:options][:ignore_xml_root])
      # TODO: Cleanup when ignore_xml_root is removed
    else
      raise ResponseParseException.new(status:status, body:@response.body, headers: @response.headers)
    end
  else
    if is_json_response? || is_xml_response?
      error_response = generate_new_object(mutable: false, ignore_xml_root: @method[:options][:ignore_xml_root])
    else
      error_response = @response.body
    end
    if status == 400
      raise HTTPBadRequestClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 401
      raise HTTPUnauthorisedClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 403
      raise HTTPForbiddenClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 404
      raise HTTPNotFoundClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 405
      raise HTTPMethodNotAllowedClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 406
      raise HTTPNotAcceptableClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 408
      raise HTTPTimeoutClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 409
      raise HTTPConflictClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 429
      raise HTTPTooManyRequestsClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 500
      raise HTTPInternalServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 501
      raise HTTPNotImplementedServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 502
      raise HTTPBadGatewayServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 503
      raise HTTPServiceUnavailableServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 504
      raise HTTPGatewayTimeoutServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif (400..499).include? status
      raise HTTPClientException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif (500..599).include? status
      raise HTTPServerException.new(status:status, result:error_response, raw_response: @response.body, url:@url, method: http_method)
    elsif status == 0
      raise TimeoutException.new("Timed out getting #{response.url}")
    end
  end
  result
end
http_method() click to toggle source
# File lib/flexirest/request.rb, line 205
def http_method
  @method[:method]
end
ignore_root() click to toggle source
# File lib/flexirest/request.rb, line 155
def ignore_root
  if @method[:options][:ignore_root]
    @method[:options][:ignore_root]
  elsif @object.nil?
    nil
  elsif object_is_class?
    @object.ignore_root
  else
    @object.class.ignore_root
  end
end
inject_basic_auth_in_url(url) click to toggle source
# File lib/flexirest/request.rb, line 131
def inject_basic_auth_in_url(url)
  url.gsub!(%r{//(.)}, "//#{username}:#{password}@\\1") if !url[%r{//[^/]*:[^/]*@}]
end
model_class() click to toggle source
# File lib/flexirest/request.rb, line 35
def model_class
  object_is_class? ? @object : @object.class
end
new_object(attributes, name = nil, parent = nil, parent_attribute_name = nil) click to toggle source
# File lib/flexirest/request.rb, line 700
def new_object(attributes, name = nil, parent = nil, parent_attribute_name = nil)
  @method[:options][:has_many] ||= {}
  name = name.to_sym rescue nil
  if @method[:options][:has_many][name]
    overridden_name = name
    object = @method[:options][:has_many][name].new
  elsif @method[:options][:has_one][name]
    overridden_name = name
    object = @method[:options][:has_one][name].new
  else
    object = create_object_instance
  end

  object._parent = parent
  object._parent_attribute_name = parent_attribute_name

  if hal_response? && name.nil?
    attributes = handle_hal_links_embedded(object, attributes)
  end

  attributes.each do |k,v|
    if @method[:options][:rubify_names]
      k = rubify_name(k)
    else
      k = k.to_sym
    end
    overridden_name = select_name(k, overridden_name)
    set_corresponding_value(v, k, object, overridden_name)
  end
  object.clean! unless object_is_class?

  object
end
object_is_class?() click to toggle source
# File lib/flexirest/request.rb, line 31
def object_is_class?
  !@object.respond_to?(:dirty?)
end
original_object_class() click to toggle source
# File lib/flexirest/request.rb, line 47
def original_object_class
  if object_is_class?
    @object
  else
    @object.class
  end
end
password() click to toggle source
# File lib/flexirest/request.rb, line 119
def password
  ret = nil
  if object_is_class?
    ret = @object.password
    ret = ret.call if ret.respond_to?(:call)
  else
   ret = @object.class.password
   ret = ret.call(@object) if ret.respond_to?(:call)
  end
  ret
end
post?() click to toggle source
# File lib/flexirest/request.rb, line 213
def post?
  http_method == :post
end
prepare_params() click to toggle source
# File lib/flexirest/request.rb, line 325
def prepare_params
  if http_method == :post || http_method == :put || http_method == :patch
    params = (@object._attributes rescue {}).merge(@params || {}) rescue {}
  else
    params = @params || @object._attributes rescue {}
  end
  if params.is_a?(String) || params.is_a?(Integer)
    params = {id:params}
  end

  # Format includes parameter for jsonapi
  if proxy == :json_api
    JsonAPIProxy::Request::Params.translate(params, @object._include_associations)
    @object._reset_include_associations!
  end

  if @method[:options][:defaults].respond_to?(:call)
    default_params = @method[:options][:defaults].call(params)
  else
    default_params = @method[:options][:defaults] || {}
  end

  if @explicit_parameters
    params = @explicit_parameters
  end
  if http_method == :get || (http_method == :delete && !@method[:options][:send_delete_body] && proxy != :json_api)
    @get_params = default_params.merge(params || {})
    @post_params = nil
  elsif http_method == :delete && @method[:options][:send_delete_body]
    @post_params = default_params.merge(params || {})
    @get_params = {}
  elsif params.is_a? String
    @post_params = params
    @get_params = {}
  else
    @post_params = (default_params || {}).merge(params || {})
    @get_params = {}
  end

  # Evaluate :only_changed
  if @method[:options][:only_changed]
    if http_method == :post or http_method == :put or http_method == :patch
      # we only ever mess with @post_params in here, because @get_params will/should never match our method criteria
      if @method[:options][:only_changed].is_a? Hash
        # only include the listed attributes marked 'true' when they are changed; attributed marked false are always included
        newPostHash = {}
        @method[:options][:only_changed].each_pair do |changed_attr_k,changed_attr_v|
          if changed_attr_v == false or @object.changes.has_key? changed_attr_k.to_sym
            newPostHash[changed_attr_k.to_sym] = @object[changed_attr_k.to_sym]
          end
        end
        @post_params = newPostHash
      elsif @method[:options][:only_changed].is_a? Array
        # only send these listed attributes, and only if they are changed
        newPostHash = {}
        @method[:options][:only_changed].each do |changed_attr|
          if @object.changes.has_key? changed_attr.to_sym
            newPostHash[changed_attr.to_sym] = @object[changed_attr.to_sym]
          end
        end
        @post_params = newPostHash
      else
        # only send attributes if they are changed, drop the rest
        newPostHash = {}
        @object.changed.each do |k|
          newPostHash[k] = @object[k]
        end
        @post_params = newPostHash
      end
    end
  end

  if @method[:options][:requires]
    requires = @method[:options][:requires].dup
    merged_params = @get_params.merge(@post_params || {})
    missing = []
    requires.each do |key|
      if merged_params[key.to_sym].blank? && ![true, false].include?(merged_params[key.to_sym])
        missing << key
      end
    end
    if missing.any?
      raise Flexirest::MissingParametersException.new("The following parameters weren't specifed: #{missing.join(", ")}")
    end
  end
end
prepare_request_body(params = nil) click to toggle source
# File lib/flexirest/request.rb, line 451
def prepare_request_body(params = nil)
  if proxy == :json_api
    if http_method == :get || (http_method == :delete && !@method[:options][:send_delete_body])
      @body = ""
    else
      headers["Content-Type"] ||= "application/vnd.api+json"
      @body = JsonAPIProxy::Request::Params.create(
        params || @post_params || {},
        object_is_class? ? @object.new : @object
      ).to_json
    end

    headers["Accept"] ||= "application/vnd.api+json"
    JsonAPIProxy::Headers.save(headers)
  elsif http_method == :get || (http_method == :delete && !@method[:options][:send_delete_body])
    if request_body_type == :form_encoded
      headers["Content-Type"] ||= "application/x-www-form-urlencoded; charset=utf-8"
    elsif request_body_type == :form_multipart
      headers["Content-Type"] ||= "multipart/form-data; charset=utf-8"
    elsif request_body_type == :json
      headers["Content-Type"] ||= "application/json; charset=utf-8"
    end
    @body = ""
  elsif request_body_type == :form_encoded
    @body ||= if params.is_a?(String)
      params
    elsif @post_params.is_a?(String)
      @post_params
    else
      p = (params || @post_params || {})
      if wrap_root.present?
        p = {wrap_root => p}
      end
      p.to_query
    end
    headers["Content-Type"] ||= "application/x-www-form-urlencoded"
  elsif request_body_type == :form_multipart
    headers["Content-Type"] ||= "multipart/form-data; charset=utf-8"
    @body ||= if params.is_a?(String)
      params
    elsif @post_params.is_a?(String)
      @post_params
    else
      p = (params || @post_params || {})
      if wrap_root.present?
        p = {wrap_root => p}
      end
      data, mp_headers = Flexirest::Multipart::Post.prepare_query(p)
      mp_headers.each do |k,v|
        headers[k] = v
      end
      data
    end
  elsif request_body_type == :json
    @body ||= if params.is_a?(String)
      params
    elsif @post_params.is_a?(String)
      @post_params
    else
      if wrap_root.present?
        {wrap_root => (params || @post_params || {})}.to_json
      else
        (params || @post_params || {}).to_json
      end
    end
    headers["Content-Type"] ||= "application/json; charset=utf-8"
  elsif request_body_type == :plain && @post_params[:body].present?
    @body = @post_params[:body]
    headers["Content-Type"] ||= "text/plain"
    headers["Content-Type"] = @post_params[:content_type] if @post_params[:content_type].present?
  end
end
prepare_url() click to toggle source
# File lib/flexirest/request.rb, line 412
def prepare_url
  missing = []
  if @forced_url && @forced_url.present?
    @url = @forced_url
  else
    @url = @method[:url].dup
    matches = @url.scan(/(:[a-z_-]+)/)
    @get_params ||= {}
    @post_params ||= {}
    matches.each do |token|
      token = token.first[1,999]
      # pull URL path variables out of @get_params/@post_params
      target = @get_params.delete(token.to_sym) || @post_params.delete(token.to_sym) || @get_params.delete(token.to_s) || @post_params.delete(token.to_s) || ""
      unless object_is_class?
        # it's possible the URL path variable may not be part of the request, in that case, try to resolve it from the object attributes
        target = @object._attributes[token.to_sym] || "" if target == ""
      end
      if target.to_s.blank?
        missing << token
      end
      @url.gsub!(":#{token}", URI.encode_www_form_component(target.to_s))
    end
  end

  if missing.present?
    raise Flexirest::MissingParametersException.new("The following parameters weren't specifed: #{missing.join(", ")}")
  end
end
proxy() click to toggle source
# File lib/flexirest/request.rb, line 195
def proxy
  if object_is_class?
    @object.proxy
  else
    @object.class.proxy
  end
rescue
  nil
end
put?() click to toggle source
# File lib/flexirest/request.rb, line 217
def put?
  http_method == :put
end
request_body_type() click to toggle source
# File lib/flexirest/request.rb, line 143
def request_body_type
  if @method[:options][:request_body_type]
    @method[:options][:request_body_type]
  elsif @object.nil?
    nil
  elsif object_is_class?
    @object.request_body_type
  else
    @object.class.request_body_type
  end
end
set_corresponding_value(value, key = nil, object = nil, overridden_name = nil) click to toggle source
# File lib/flexirest/request.rb, line 734
def set_corresponding_value(value, key = nil, object = nil, overridden_name = nil)
  optional_args = [key, object, overridden_name]
  value_from_object = optional_args.all? # trying to parse a JSON Hash value
  value_from_other_type = optional_args.none? # trying to parse anything else
  raise Flexirest::InvalidArgumentsException.new("Optional args need all to be filled or none") unless value_from_object || value_from_other_type
  k = key || :key
  v = value
  assignable_hash = value_from_object ? object._attributes : {}
  if value_from_object && @method[:options][:lazy].include?(k)
    assignable_hash[k] = Flexirest::LazyAssociationLoader.new(overridden_name, v, self, overridden_name:(overridden_name), parent: object, parent_attribute_name: k)
  elsif v.is_a? Hash
    assignable_hash[k] = new_object(v, overridden_name, object, k)
  elsif v.is_a? Array
    if @method[:options][:array].include?(k)
      assignable_hash[k] = Array.new
    else
      assignable_hash[k] = Flexirest::ResultIterator.new
    end
    v.each do |item|
      if item.is_a? Hash
        assignable_hash[k] << new_object(item, overridden_name)
      else
        assignable_hash[k] << set_corresponding_value(item)
      end
    end
  else
    parse_fields = [ @method[:options][:parse_fields], @object._date_fields ].compact.reduce([], :|)
    parse_fields = nil if parse_fields.empty?
    if (parse_fields && parse_fields.include?(k))
      assignable_hash[k] = parse_attribute_value(v)
    elsif parse_fields
      assignable_hash[k] = v
    elsif Flexirest::Base.disable_automatic_date_parsing
      assignable_hash[k] = v
    else
      assignable_hash[k] = parse_attribute_value(v)
    end
  end
  value_from_object ? object : assignable_hash[k]
end
translator() click to toggle source
# File lib/flexirest/request.rb, line 187
def translator
  if object_is_class?
    @object.translator
  else
    @object.class.translator
  end
end
username() click to toggle source
# File lib/flexirest/request.rb, line 107
def username
  ret = nil
  if object_is_class?
    ret = @object.username
    ret = ret.call if ret.respond_to?(:call)
  else
    ret = @object.class.username
    ret = ret.call(@object) if ret.respond_to?(:call)
  end
  ret
end
using_api_auth?() click to toggle source
# File lib/flexirest/request.rb, line 67
def using_api_auth?
  if object_is_class?
    @object.using_api_auth?
  else
    @object.class.using_api_auth?
  end
end
using_basic_auth?() click to toggle source
# File lib/flexirest/request.rb, line 135
def using_basic_auth?
  !!username
end
verbose?() click to toggle source
# File lib/flexirest/request.rb, line 179
def verbose?
  if object_is_class?
    @object.verbose
  else
    @object.class.verbose
  end
end
wrap_root() click to toggle source
# File lib/flexirest/request.rb, line 167
def wrap_root
  if @method[:options][:wrap_root]
    @method[:options][:wrap_root]
  elsif @object.nil?
    nil
  elsif object_is_class?
    @object.wrap_root
  else
    @object.class.wrap_root
  end
end

Private Instance Methods

add_nested_body_to_iterator(result, items) click to toggle source
# File lib/flexirest/request.rb, line 903
def add_nested_body_to_iterator(result, items)
  items.each do |json_object|
    if json_object.is_a? Hash
      result << new_object(json_object, @overridden_name)
    else
      result << set_corresponding_value(json_object)
    end
  end
end
create_object_instance() click to toggle source
# File lib/flexirest/request.rb, line 824
def create_object_instance
  return object_is_class? ? @object.new : @object.class.new
end
generate_new_object(options={}) click to toggle source
# File lib/flexirest/request.rb, line 848
def generate_new_object(options={})
  if @response.body.is_a?(Array) || @response.body.is_a?(Hash)
    body = @response.body
  elsif is_json_response?
    begin
      body = @response.body.blank? ? {} : MultiJson.load(@response.body)
      body = {} if body.nil?
    rescue MultiJson::ParseError
      raise ResponseParseException.new(status:@response.status, body:@response.body, headers:@response.headers)
    end

    if is_json_api_response?
      body = JsonAPIProxy::Response.parse(body, @object)
    end

    if ignore_root
      [ignore_root].flatten.each do |key|
        body = body[key.to_s] if body.has_key?(key.to_s)
      end
    end
  elsif is_xml_response?
    body = @response.body.blank? ? {} : Crack::XML.parse(@response.body)
    if ignore_root
      [ignore_root].flatten.each do |key|
        body = body[key.to_s] if body.has_key?(key.to_s)
      end
    elsif options[:ignore_xml_root]
      Flexirest::Logger.warn("Using `ignore_xml_root` is deprecated, please switch to `ignore_root`")
      body = body[options[:ignore_xml_root].to_s]
    end
  end
  if translator
    body = begin
      @method[:name].nil? ? body : translator.send(@method[:name], body)
    rescue NoMethodError
      body
    end
  end
  if body.is_a? Array
    result = Flexirest::ResultIterator.new(@response)
    add_nested_body_to_iterator(result, body)
  else
    result = new_object(body, @overridden_name)
    result._status = @response.status
    result._headers = @response.response_headers
    result._etag = @response.response_headers['ETag'] unless @method[:options][:skip_caching]
    if !object_is_class? && options[:mutable] != false
      @object._copy_from(result)
      @object._clean!
      result = @object
    end
  end
  result
end
is_json_api_response?() click to toggle source
# File lib/flexirest/request.rb, line 840
def is_json_api_response?
  @response.response_headers['Content-Type'] && @response.response_headers['Content-Type'].include?('application/vnd.api+json')
end
is_json_response?() click to toggle source
# File lib/flexirest/request.rb, line 836
def is_json_response?
  @response.response_headers['Content-Type'].nil? || @response.response_headers['Content-Type'].include?('json')
end
is_xml_response?() click to toggle source
# File lib/flexirest/request.rb, line 844
def is_xml_response?
  @response.response_headers['Content-Type'].include?('xml')
end
rubify_name(k) click to toggle source
# File lib/flexirest/request.rb, line 913
def rubify_name(k)
  k.underscore.to_sym
end
select_name(name, parent_name) click to toggle source
# File lib/flexirest/request.rb, line 828
def select_name(name, parent_name)
  if @method[:options][:has_many][name] || @method[:options][:has_one][name]
    return name
  end

  parent_name || name
end