class Cubits::Connection
Constants
- CONTENT_TYPE
Public Class Methods
new(params)
click to toggle source
Creates a new Connection
object
@param params [Hash] @param params [String] @param params [String]
# File lib/cubits/connection.rb, line 17 def initialize(params) fail ArgumentError, 'String is expected as :key' unless params[:key].is_a?(String) fail ArgumentError, 'String is expected as :secret' unless params[:secret].is_a?(String) @key = params[:key] @secret = params[:secret] @params = params.dup end
Private Class Methods
nonce()
click to toggle source
Returns timestamp based nonce
@return [Integer]
# File lib/cubits/connection.rb, line 106 def self.nonce (Time.now.to_f * 1000).to_i end
Public Instance Methods
get(path, data = {})
click to toggle source
Executes a GET request
# File lib/cubits/connection.rb, line 27 def get(path, data = {}) fail ArgumentError, 'Hash is expected as request data' unless data.is_a?(Hash) encoded_data = URI.encode_www_form(data) request(:get, path, encoded_data) end
post(path, data = {})
click to toggle source
Executes a POST request
# File lib/cubits/connection.rb, line 35 def post(path, data = {}) fail ArgumentError, 'Hash is expected as request data' unless data.is_a?(Hash) encoded_data = data.to_json request(:post, path, encoded_data) end
sign_message(msg)
click to toggle source
Signs the message with preconfigured secret
@param msg [String]
@return [String] Calculated signature
# File lib/cubits/connection.rb, line 47 def sign_message(msg) OpenSSL::HMAC.hexdigest('sha512', @secret, msg) end
Private Instance Methods
cubits_headers(path, encoded_data)
click to toggle source
Returns complete set of cubits headers
# File lib/cubits/connection.rb, line 112 def cubits_headers(path, encoded_data) nonce = self.class.nonce signature = sign_request(path, nonce, encoded_data) { 'CUBITS_KEY' => @key, 'CUBITS_NONCE' => nonce, 'CUBITS_SIGNATURE' => signature, 'Accept' => CONTENT_TYPE } end
insecure?()
click to toggle source
Returns true if an insecure connection is requested (do NOT use in production)
# File lib/cubits/connection.rb, line 152 def insecure? @insecure ||= @params[:insecure] || Cubits.base_url.scheme != 'https' end
request(method, path, encoded_data)
click to toggle source
Sends a request to the API
# File lib/cubits/connection.rb, line 55 def request(method, path, encoded_data) Cubits.logger.warn 'Connecting to Cubits using insecure connection!' if insecure? url = URI.join(Cubits.base_url, path) params = {} http = HTTP.with(cubits_headers(path, encoded_data)) if method == :get url.query = encoded_data unless encoded_data.empty? else http = http.with('Content-Type' => CONTENT_TYPE) params[:body] = encoded_data end params[:ssl_context] = ssl_context unless insecure? Cubits.logger.debug "> #{method.to_s.upcase}: #{url}" response = http.send(method, url, params) Cubits.logger.debug "< #{response.code} #{response.reason}" begin body = JSON.parse(response.body) rescue JSON::ParserError => e raise ConnectionError, "Failed to parse response: #{e}" end return body if (200...300).include?(response.status) respond_with_error(response.code, body['message']) end
respond_with_error(status, message)
click to toggle source
Map unsuccessful HTTP response to appropriate exception and raise it
# File lib/cubits/connection.rb, line 81 def respond_with_error(status, message) case status when 400 fail BadRequest, message when 403 fail Forbidden, message when 404 fail NotFound, message when 415 fail UnsupportedMediaType, message when 500 fail InternalServerError, message when 400...500 fail ClientError, message when 500...600 fail ServerError, message else fail ConnectionError, message end end
sign_request(path, nonce, request_data)
click to toggle source
Calculates request signature
@param path [String] @param nonce [Integer,String] @param request_data [String]
# File lib/cubits/connection.rb, line 130 def sign_request(path, nonce, request_data) msg = path + nonce.to_s + OpenSSL::Digest::SHA256.hexdigest(request_data) signature = sign_message(msg) Cubits.logger.debug 'sign_request: ' \ "path=#{path} nonce=#{nonce} request_data=#{request_data} msg=#{msg} signature=#{signature}" signature end
ssl_context()
click to toggle source
Returns configured SSLContext
# File lib/cubits/connection.rb, line 140 def ssl_context return @ssl_context if @ssl_context @ssl_context = OpenSSL::SSL::SSLContext.new @ssl_context.verify_mode = OpenSSL::SSL::VERIFY_PEER cert_store = OpenSSL::X509::Store.new cert_store.set_default_paths @ssl_context.cert_store = cert_store @ssl_context end