class Crossbar::HTTP::Client
Attributes
Public Class Methods
# File lib/crossbar-http/client.rb, line 133 def self._get_nonce rand(0..2**53) end
# File lib/crossbar-http/client.rb, line 129 def self._get_timestamp Time.now.utc.strftime('%Y-%m-%dT%H:%M:%S.%LZ') end
Initializes the client @param url [String] - The url of the router's HTTP
bridge @param key [String] - The key (optional) @param secret [String] - The secret (optional) @param verbose [Bool] - 'True' if you want debug messages printed @param pre_serialize
[lambda] - Lambda to format the data
# File lib/crossbar-http/client.rb, line 44 def initialize(url, key: nil, secret: nil, verbose: false, pre_serialize: nil) raise 'The url can not be nil' unless url != nil self.url = url self.key = key self.secret = secret self.verbose = verbose self.pre_serialize = pre_serialize self.sequence = 1 end
Public Instance Methods
This method makes tha API call. It is a class method so it can be more easily stubbed for testing @param uri [URI] The uri of the request @param body [String] The body of the request @return [Hash] The response from the server
# File lib/crossbar-http/client.rb, line 181 def _api_call(uri, body=nil) # Create the request res = Net::HTTP.start(uri.hostname, uri.port, :use_ssl => uri.scheme == 'https') do |http| req = Net::HTTP::Post.new(uri) req['Content-Type'] = 'application/json' req.body = body http.request(req) end case res when Net::HTTPSuccess puts "Crossbar::HTTP - Response Body: #{res.body}" if self.verbose return JSON.parse(res.body, {:symbolize_names => true}) else raise "Crossbar::HTTP - Code: #{res.code}, Error: #{res.message}" end end
Computes the signature. Described at: crossbar.io/docs/HTTP-Bridge-Services-Caller/ Reference code is at: github.com/crossbario/crossbar/blob/master/crossbar/adapter/rest/common.py @param body [Hash] @return (signature, nonce, timestamp)
# File lib/crossbar-http/client.rb, line 113 def _compute_signature(body) timestamp = self.class._get_timestamp nonce = self.class._get_nonce # Compute signature: HMAC[SHA256]_{secret} (key | timestamp | seq | nonce | body) => signature hm = OpenSSL::HMAC.new(self.secret, OpenSSL::Digest::SHA256.new) hm << self.key hm << timestamp hm << self.sequence.to_s hm << nonce.to_s hm << body signature = Base64.urlsafe_encode64(hm.digest) return signature, nonce, timestamp end
Performs the API call @param json_params [Hash,nil] The parameters that will make up the body of the request @return [Hash] The response from the server
# File lib/crossbar-http/client.rb, line 140 def _make_api_call(json_params=nil) puts "Crossbar::HTTP - Request: POST #{url}" if self.verbose encoded_params = nil if json_params != nil if self.pre_serialize != nil and self.pre_serialize.is_a? Proc json_params = self._parse_params json_params end encoded_params = JSON.generate(json_params) end puts "Crossbar::HTTP - Params: #{encoded_params}" if encoded_params != nil and self.verbose uri = URI(self.url) if self.key != nil and self.secret != nil and encoded_params != nil signature, nonce, timestamp = self._compute_signature(encoded_params) params = { timestamp: timestamp, seq: self.sequence.to_s, nonce: nonce, signature: signature, key: self.key } uri.query = URI.encode_www_form(params) puts "Crossbar::HTTP - Signature Params: #{params}" if self.verbose end # TODO: Not sure what this is supposed to be but this works self.sequence += 1 self._api_call uri, encoded_params end
Parses the params to pre-serialize the overrides
# File lib/crossbar-http/client.rb, line 89 def _parse_params(params) if params.is_a? Hash return_value = {} params.each do |key, value| return_value[key] = self._parse_params(value) end elsif params.is_a? Array return_value = [] params.each_index {|i| return_value.push(self._parse_params (params[i])) } else return_value = self.pre_serialize.call(params) || params end return_value end
Calls the procedure @param procedure [String] - The name of the topic @param *args [] - The arguments and key word arguments @return [Integer] - Returns the id of the publish
# File lib/crossbar-http/client.rb, line 76 def call(procedure, *args, **kwargs) raise 'The topic can not be nil' unless url != nil params = { procedure: procedure, args: args, kwargs: kwargs } self._make_api_call(params) end
Publishes to the topic @param topic [String] - The name of the topic @param *args [] - The arguments and key word arguments @return [Integer] - Returns the id of the publish
# File lib/crossbar-http/client.rb, line 60 def publish(topic, *args, **kwargs) raise 'The topic can not be nil' unless url != nil params = { topic: topic, args: args, kwargs: kwargs } self._make_api_call(params) end