From 429837b61087e829089101c480639b32de311281 Mon Sep 17 00:00:00 2001 From: Stephen Paul Weber Date: Thu, 16 Mar 2017 18:15:41 -0500 Subject: [PATCH] First HTTP request using em-http --- .rubocop.yml | 6 ++++ Gemfile | 2 ++ em_promise.rb | 40 +++++++++++++++++++++++++ sgx-catapult.rb | 79 ++++++++++++++++++++++++++++--------------------- 4 files changed, 93 insertions(+), 34 deletions(-) create mode 100644 em_promise.rb diff --git a/.rubocop.yml b/.rubocop.yml index 41481b07ca04fd99056d8c06d984452221235343..574c2129dc91242ea4495a1ebb525a14e2efc028 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -93,3 +93,9 @@ Style/NegatedIf: Style/RedundantReturn: Enabled: false + +Style/MultilineBlockChain: + Enabled: false + +Style/SpaceAroundEqualsInParameterDefault: + EnforcedStyle: no_space diff --git a/Gemfile b/Gemfile index 5006d96e1c8d0d1ab0d09ea0f83b3cfc179af34d..1886af41a6dcc06667a0174497d3bfd85a48418e 100644 --- a/Gemfile +++ b/Gemfile @@ -2,7 +2,9 @@ source 'https://rubygems.org' gem 'activesupport', '<5.0.0' gem 'blather' +gem 'em-http-request' gem 'eventmachine', '1.0.0' +gem 'promise.rb' gem 'hiredis', '~> 0.6.0' gem 'redis', '>= 3.2.0' diff --git a/em_promise.rb b/em_promise.rb new file mode 100644 index 0000000000000000000000000000000000000000..96e25425d4a4de9fbfa8289f0fb1a88b8a3f6498 --- /dev/null +++ b/em_promise.rb @@ -0,0 +1,40 @@ +require "eventmachine" +require "promise" + +class EMPromise < Promise + def initialize(deferrable=nil) + super() + fulfill(deferrable) if deferrable + end + + def fulfill(value, bind_defer=true) + if bind_defer && value.is_a?(EM::Deferrable) + value.callback { |x| fulfill(x, false) } + value.errback(&method(:reject)) + else + super(value) + end + end + + def defer + EM.next_tick { yield } + end + + def self.reject(e) + new.tap { |promise| promise.reject(e) } + end +end + +module EventMachine + module Deferrable + def promise + EMPromise.new(self) + end + + [:then, :rescue, :catch].each do |method| + define_method(method) do |*args, &block| + promise.public_send(method, *args, &block) + end + end + end +end diff --git a/sgx-catapult.rb b/sgx-catapult.rb index 68efdd4cfdd3830c035dc2369146c1b23c705b05..d90f43ca4319e473b10b57c7b2fe072d2bbd9931 100755 --- a/sgx-catapult.rb +++ b/sgx-catapult.rb @@ -19,6 +19,7 @@ # with sgx-catapult. If not, see . require 'blather/client/dsl' +require 'em-http-request' require 'json' require 'net/http' require 'redis/connection/hiredis' @@ -31,6 +32,8 @@ require 'goliath/api' require 'goliath/server' require 'log4r' +require_relative 'em_promise' + $stdout.sync = true puts "Soprani.ca/SMS Gateway for XMPP - Catapult\n"\ @@ -47,6 +50,14 @@ end t = Time.now puts "LOG %d.%09d: starting...\n\n" % [t.to_i, t.nsec] +def panic(e) + puts "Shutting down gateway due to exception: #{e.message}" + puts e.backtrace + SGXcatapult.shutdown + puts 'Gateway has terminated.' + EM.stop +end + module SGXcatapult extend Blather::DSL @@ -63,7 +74,7 @@ module SGXcatapult client.write(stanza) end - def self.error_msg(orig, query_node, type, name, text = nil) + def self.error_msg(orig, query_node, type, name, text=nil) if not query_node.nil? orig.add_child(query_node) orig.type = :error @@ -169,39 +180,39 @@ module SGXcatapult conn.disconnect - uri = URI.parse('https://api.catapult.inetwork.com') - http = Net::HTTP.new(uri.host, uri.port) - http.use_ssl = true - request = Net::HTTP::Post.new('/v1/users/' + user_id + - '/messages') - request.basic_auth api_token, api_secret - request.add_field('Content-Type', 'application/json') - request.body = JSON.dump( - 'from' => users_num, - 'to' => num_dest, - 'text' => m.body, - 'tag' => - # callbacks need both the id and resourcepart - WEBrick::HTTPUtils.escape(m.id.to_s) + ' ' + - WEBrick::HTTPUtils.escape( - m.from.to_s.split('/', 2)[1].to_s - ), - 'receiptRequested' => 'all', - 'callbackUrl' => ARGV[6] - ) - response = http.request(request) - - puts 'API response to send: ' + response.to_s + ' with code ' + - response.code + ', body "' + response.body + '"' - - if response.code != '201' - # TODO: add text re unexpected code; mention code number - write_to_stream error_msg( - m.reply, m.body, :cancel, - 'internal-server-error' + EM::HttpRequest.new( + "https://api.catapult.inetwork.com/"\ + "v1/users/#{user_id}/messages" + ).post( + head: { + 'Authorization' => [api_token, api_secret], + 'Content-Type' => 'application/json' + }, + body: JSON.dump( + from: users_num, + to: num_dest, + text: m.body, + tag: + # callbacks need both the id and resourcepart + WEBrick::HTTPUtils.escape(m.id.to_s) + ' ' + + WEBrick::HTTPUtils.escape( + m.from.to_s.split('/', 2)[1].to_s + ), + receiptRequested: 'all', + callbackUrl: ARGV[6] ) - next - end + ).then { |http| + puts "API response to send: #{http.response} with code "\ + "response.code #{http.response_header.status}" + + if http.response_header.status != 201 + # TODO: add text re unexpected code; mention code number + write_to_stream error_msg( + m.reply, m.body, :cancel, + 'internal-server-error' + ) + end + }.catch(&method(:panic)) rescue Exception => e puts 'Shutting down gateway due to exception 001: ' + e.message @@ -950,7 +961,7 @@ end end class ReceiptMessage < Blather::Stanza - def self.new(to = nil) + def self.new(to=nil) node = super :message node.to = to node