class NCMB::Client

Attributes

api_version[RW]
application_key[RW]
client_key[RW]
domain[RW]
script_api_version[RW]

Public Class Methods

new(params = {}) click to toggle source
# File lib/ncmb/client.rb, line 24
def initialize(params = {})
  @domain          = NCMB::DOMAIN
  @api_version     = NCMB::API_VERSION
  @script_domain   = NCMB::SCRIPT_DOMAIN
  @script_api_version = NCMB::SCRIPT_API_VERSION
  @application_key = params[:application_key]
  @client_key      = params[:client_key]
end

Public Instance Methods

array2hash(ary) click to toggle source
# File lib/ncmb/client.rb, line 49
def array2hash(ary)
  new_v = {}
  ary.each do |hash|
    if hash.is_a? Hash
      key = hash.keys[0]
      new_v[key] = hash[key]
    else
      new_v = [hash]
    end
  end
  new_v = new_v.sort_by{|a, b| a.to_s}.to_h
  new_v
end
change_query(queries = {}) click to toggle source
# File lib/ncmb/client.rb, line 73
def change_query(queries = {})
  results = {}
  queries.each do |k, v|
    case v
    when NCMB::Increment
      queries[k] = v.amount
    end
  end
  queries
end
delete(path, params = {}, headers = {}) click to toggle source
# File lib/ncmb/client.rb, line 45
def delete(path, params = {}, headers = {})
  request :delete, path, params, headers
end
encode_query(queries = {}) click to toggle source
# File lib/ncmb/client.rb, line 63
def encode_query(queries = {})
  results = {}
  queries.each do |k, v|
    v = array2hash(v) if v.is_a? Array
    value = URI.encode_www_form_component(v.is_a?(Hash) ? v.to_json : v.to_s).gsub("[", "%5B").gsub(":", "%3A").gsub("]", "%5D")
    results[k.to_s] = value
  end
  results
end
generate_signature(method, path, now = nil, queries = {}) click to toggle source
# File lib/ncmb/client.rb, line 100
def generate_signature(method, path, now = nil, queries = {})
  params_base = {
    "SignatureMethod" => "HmacSHA256",
    "SignatureVersion" => "2",
    "X-NCMB-Application-Key" => @application_key
  }
  params = method == :get ? params_base.merge(encode_query(queries)) : params_base
  now ||= Time.now.utc.iso8601
  params = params.merge "X-NCMB-Timestamp" => now
  if [].respond_to?("to_h") # Array#to_h inpremented over ruby 2.1
    params = params.sort_by{|a, b| a.to_s}.to_h
  else
    sorted_params = {}
    params = params.sort_by{|a, b| a.to_s}.each {|kv|
      sorted_params[kv[0]] = kv[1]
    }
    params = sorted_params
  end
  signature_base = []
  signature_base << method.upcase
  signature_base << get_domain(path)
  signature_base << path
  signature_base << params.collect{|k,v| "#{k}=#{v}"}.join("&")
  Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), @client_key, signature_base.join("\n"))).strip()
end
get(path, params = {}, headers = {}) click to toggle source
# File lib/ncmb/client.rb, line 33
def get(path, params = {}, headers = {})
  request :get, path, params, headers
end
get_domain(path) click to toggle source
# File lib/ncmb/client.rb, line 141
def get_domain(path)
  domain = @domain
  if path.start_with?("/#{@script_api_version}/script\/")
    domain = @script_domain
  end
  domain
end
hash2query(queries = {}) click to toggle source
# File lib/ncmb/client.rb, line 84
def hash2query(queries = {})
  results = {}
  queries.each do |k, v|
    # v = array2hash(v) if v.is_a? Array
    puts "#{k} -> #{v.class}"
    case v
    when Hash, TrueClass, FalseClass, Array then
      results[k.to_s] = v
    when Time then
    else
      results[k.to_s] = v.to_s
    end
  end
  results
end
make_boundary(boundary, queries) click to toggle source
# File lib/ncmb/client.rb, line 126
def make_boundary(boundary, queries)
  post_body = []
  post_body << "--#{boundary}"
  post_body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{queries[:fileName]}\""
  post_body << "Content-Type: #{queries['mime-type'.to_sym]}"
  post_body << queries[:file].read
  post_body << ""
  post_body << "--#{boundary}"
  post_body << "Content-Disposition: form-data; name=\"acl\""
  post_body << ""
  post_body << queries[:acl].to_json
  post_body << "--#{boundary}--"
  post_body.join("\r\n")
end
post(path, params = {}, headers = {}) click to toggle source
# File lib/ncmb/client.rb, line 37
def post(path, params = {}, headers = {})
  request :post, path, params, headers
end
put(path, params = {}, headers = {}) click to toggle source
# File lib/ncmb/client.rb, line 41
def put(path, params = {}, headers = {})
  request :put, path, params, headers
end
request(method, path, queries = {}, addHeaders = {}) click to toggle source
# File lib/ncmb/client.rb, line 149
def request(method, path, queries = {}, addHeaders = {})
  now = Time.now.utc.iso8601
  signature = generate_signature(method, path, now, queries)
  domain = get_domain(path)
  http = Net::HTTP.new(domain, 443)
  http.use_ssl=true
  headers = {
    "X-NCMB-Application-Key" => @application_key,
    "X-NCMB-Signature" => signature,
    "X-NCMB-Timestamp" => now,
    "Content-Type" => 'application/json'
  }
  Array(addHeaders || {}).each do |name, value|
    headers[name] = value
  end
  if NCMB.CurrentUser
    headers['X-NCMB-Apps-Session-Token'] = NCMB.CurrentUser[:sessionToken]
  end
  # queries = hash2query(queries)
  json = nil
  begin
    case method
    when :get
      query = encode_query(queries).map do |key, value|
        "#{key}=#{value}"
      end.join("&")
      path = path + (query == '' ? "" : "?"+query)
      rp = Regexp.new "/#{NCMB::API_VERSION}/files/.*"
      if path =~ rp
        json = http.get(path, headers).body
      else
        json = JSON.parse(http.get(path, headers).body, symbolize_names: true)
      end
    when :post
      req = Net::HTTP::Post.new(path)
      if path.include? "/2013-09-01/files"
        boundary = SecureRandom.uuid
        req.body = make_boundary(boundary, queries)
        headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
      else
        queries = change_query(queries)
        req.body = queries.to_json
      end
      headers.each do |key, value|
        req[key] = value
      end
      json =  JSON.parse(http.request(req).body, symbolize_names: true)
    when :put
      req = Net::HTTP::Put.new(path)
      if queries[:file].is_a?(File) || queries[:file].is_a?(StringIO)
        boundary = SecureRandom.uuid
        req.body = make_boundary(boundary, queries)
        headers["Content-Type"] = "multipart/form-data; boundary=#{boundary}"
      else
        queries = change_query(queries)
        req.body = queries.to_json
      end
      headers.each do |key, value|
        req[key] = value
      end
      json =  JSON.parse(http.request(req).body, symbolize_names: true)
    when :delete
      response = http.delete(path, headers).body
      return true if response == ""
      json = JSON.parse(response, symbolize_names: true)
    end
  rescue => e
    @@last_error =  e
    raise NCMB::APIError.new(e.to_s)
  end
  if json.is_a?(Hash) && json[:error] != nil
    raise NCMB::APIError.new(json[:error])
  end
  json
end