lib/hik_openapi.rb in hik_openapi-0.1.2 vs lib/hik_openapi.rb in hik_openapi-0.2
- old
+ new
@@ -1,25 +1,96 @@
# frozen_string_literal: true
require 'hik_openapi/version'
-require 'hik_openapi/configuration'
-require 'hik_openapi/api'
-require 'hik_openapi/result'
+require 'securerandom'
+require 'openssl'
+require 'http'
module HikOpenapi
- class Error < StandardError; end
+ class Client
+ attr_accessor :host, :prefix, :app_key, :app_secret, :proxy, :timeouts
+ attr_writer :user_agent
- def self.config
- return @config if defined?(@config)
+ def initialize(options = {})
+ options.each do |key, value|
+ instance_variable_set("@#{key}", value)
+ end
+ yield(self) if block_given?
+ end
- @config = Configuration.new
- @config
- end
+ def get(path, params)
+ request(:get, path, params)
+ end
- def self.setup
- yield config
- end
+ def post(path, params)
+ request(:post, path, params)
+ end
- def self.api
- Api
+ private
+
+ def request(request_method, path, params)
+ @uri = host + prefix + path
+ @request_method = request_method
+ @path = path
+ @params = params
+ @options_key = {get: :params, post: :json}[request_method] || :form
+ @headers = {'Content-Type': 'application/json', 'Accept': '*/*', 'x-ca-timestamp': (Time.now.to_f * 1000).to_i.to_s, 'x-ca-nonce': SecureRandom.uuid, 'x-ca-key': app_key}
+ perform
+ end
+
+ def perform
+ ctx = OpenSSL::SSL::SSLContext.new
+ ctx.verify_mode = OpenSSL::SSL::VERIFY_NONE
+
+ response = http_client.headers(sign_headers(@headers)).public_send(@request_method, @uri.to_s, request_options.merge(ssl_context: ctx))
+ response_body = response.body.empty? ? '' : symbolize_keys!(response.parse)
+ response_headers = response.headers
+ {
+ headers: response_headers,
+ body: response_body,
+ }
+ end
+
+ def symbolize_keys!(object)
+ case object
+ when Array
+ object.each_with_index { |val, index| object[index] = symbolize_keys!(val) }
+ when Hash
+ object.dup.each_key { |key| object[key.to_sym] = symbolize_keys!(object.delete(key)) }
+ end
+ object
+ end
+
+ def timeout_keys_defined
+ (%i[write connect read] - (timeouts&.keys || [])).empty?
+ end
+
+ def http_client
+ client = proxy ? HTTP.via(*proxy.values_at(:host, :port, :username, :password).compact) : HTTP
+ client = client.timeout(connect: timeouts[:connect], read: timeouts[:read], write: timeouts[:write]) if timeout_keys_defined
+ client
+ end
+
+ def request_options
+ {@options_key => @params}
+ end
+
+ def sign_headers(headers)
+ headers.merge!({
+ "x-ca-signature": sign(@request_method, (prefix + @path), headers),
+ })
+ end
+
+ def sign(method, path, headers)
+ sign_str = headers.reject { |a| a.to_s.start_with?('x-ca') }.values.sort
+ sign_str = sign_str.unshift(method.to_s.upcase).push(path).join("\n")
+
+ Base64.encode64(
+ OpenSSL::HMAC.digest(
+ OpenSSL::Digest.new('sha256'),
+ app_secret,
+ sign_str
+ )
+ ).strip
+ end
end
end