class Hyperb::Request

wraps all requests, performing aws4 signature

Constants

ALGORITHM
FMT
KEYPARTS_REQUEST
SERVICE
VERSION

Attributes

client[RW]
date[RW]
headers[RW]
path[RW]
signed[RW]
verb[RW]

Public Class Methods

new(client, path, query = {}, verb = 'GET', body = '', optional_headers = {}) click to toggle source
# File lib/hyperb/request.rb, line 21
def initialize(client, path, query = {}, verb = 'GET', body = '', optional_headers = {})
  @client = client
  @path = VERSION + path
  @query = URI.encode_www_form(query)
  @body = body.empty? ? body : body.to_json
  @hashed_body = hexdigest(@body)
  @verb = verb.upcase
  @date = Time.now.utc.strftime(FMT)

  set_base_url

  @headers = {
    content_type: 'application/json',
    x_hyper_date: @date,
    host: @host,
    x_hyper_content_sha256: @hashed_body
  }
  @headers.merge!(optional_headers) unless optional_headers.empty?
  @signed = false
end

Public Instance Methods

canonical_headers() click to toggle source

sorts all headers, join them by `:`, and re-join by n ie: content-type:applicationnhost:us-west-1.hyper.sh

# File lib/hyperb/request.rb, line 72
def canonical_headers
  canonical = @headers.sort.map do |header, value|
    "#{header.to_s.tr('_', '-')}:#{value}"
  end
  canonical.join("\n") + "\n"
end
canonical_request() click to toggle source
# File lib/hyperb/request.rb, line 103
def canonical_request
  [
    @verb,
    @path,
    @query,
    canonical_headers,
    signed_headers,
    @hashed_body
  ].join("\n")
end
credential_scope() click to toggle source
# File lib/hyperb/request.rb, line 114
def credential_scope
  [
    @date[0, 8],
    'us-west-1',
    SERVICE,
    KEYPARTS_REQUEST
  ].join("/") # rubocop:disable StringLiterals
end
fail_or_return(code, body) click to toggle source
# File lib/hyperb/request.rb, line 56
def fail_or_return(code, body)
  error = Hyperb::Error::ERRORS[code]
  raise(error.new(body, code)) if error
  body
end
hexdigest(value) click to toggle source
# File lib/hyperb/request.rb, line 123
def hexdigest(value)
  Digest::SHA256.new.update(value).hexdigest
end
hexhmac(key, value) click to toggle source
# File lib/hyperb/request.rb, line 131
def hexhmac(key, value)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), key, value)
end
hmac(key, value) click to toggle source
# File lib/hyperb/request.rb, line 127
def hmac(key, value)
  OpenSSL::HMAC.digest(OpenSSL::Digest.new('sha256'), key, value)
end
perform() click to toggle source
# File lib/hyperb/request.rb, line 47
def perform
  sign unless signed
  final = @base_url + @path + '?' + @query
  options = {}
  options[:body] = @body unless @body.empty?
  response = HTTP.headers(@headers).public_send(@verb.downcase.to_sym, final, options)
  fail_or_return(response.code, response.body)
end
set_base_url() click to toggle source
# File lib/hyperb/request.rb, line 42
def set_base_url
  @host = "#{client.region}.hyper.sh".freeze
  @base_url = "https://#{@host}/".freeze
end
sign() click to toggle source

creates Authoriatization header

# File lib/hyperb/request.rb, line 80
def sign
  credential = "#{@client.access_key}/#{credential_scope}"
  auth = "#{ALGORITHM} Credential=#{credential}, "
  auth += "SignedHeaders=#{signed_headers}, "
  auth += "Signature=#{signature}"
  @headers[:authorization] = auth
  @signed = true
end
signature() click to toggle source

setup signature key docs.hyper.sh/Reference/API/2016-04-04%20[Ver.%201.23]/index.html

# File lib/hyperb/request.rb, line 91
def signature
  k_date = hmac('HYPER' + @client.secret_key, @date[0, 8])
  k_region = hmac(k_date, 'us-west-1')
  k_service = hmac(k_region, SERVICE)
  k_credentials = hmac(k_service, KEYPARTS_REQUEST)
  hexhmac(k_credentials, string_to_sign)
end
signed_headers() click to toggle source

join all headers by `;` ie: content-type;x-hyper-hmac-sha256

# File lib/hyperb/request.rb, line 65
def signed_headers
  @headers.keys.sort.map { |header| header.to_s.tr('_', '-') }.join(';')
end
string_to_sign() click to toggle source
# File lib/hyperb/request.rb, line 99
def string_to_sign
  [ALGORITHM, @date, credential_scope, hexdigest(canonical_request)].join("\n")
end