Skip to content

Commit

Permalink
Allow API base url configuration
Browse files Browse the repository at this point in the history
Adds the `base_url` and `ca_file` client configuration options
which will be used as the base url when connecting to the API.
Defaults to `https://v3.recurly.com` and the bundled ca file in the
repo.
  • Loading branch information
cbarton committed Oct 29, 2021
1 parent edfd949 commit 7b660ce
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
14 changes: 10 additions & 4 deletions lib/recurly/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
require "net/https"
require "base64"
require "securerandom"
require "uri"
require_relative "./schema/json_parser"
require_relative "./schema/file_parser"

module Recurly
class Client
require_relative "./client/operations"

BASE_HOST = "v3.recurly.com"
BASE_PORT = 443
BASE_URL = "https://v3.recurly.com"
CA_FILE = File.join(File.dirname(__FILE__), "../data/ca-certificates.crt")
BINARY_TYPES = [
"application/pdf",
Expand Down Expand Up @@ -54,10 +54,11 @@ class Client
#
# @param api_key [String] The private API key
# @param logger [Logger] A logger to use. Defaults to creating a new STDOUT logger with level WARN.
def initialize(api_key:, logger: nil)
def initialize(base_url: BASE_URL, ca_file: CA_FILE, api_key:, logger: nil)
raise ArgumentError, "'api_key' must be set to a non-nil value" if api_key.nil?

set_api_key(api_key)
set_connection_options(base_url, ca_file)

if logger.nil?
@logger = Logger.new(STDOUT).tap do |l|
Expand Down Expand Up @@ -158,7 +159,7 @@ class << self
end

def run_request(request, options = {})
self.class.connection_pool.with_connection do |http|
self.class.connection_pool.with_connection(uri: @base_uri, ca_file: @ca_file) do |http|
set_http_options(http, options)

retries = 0
Expand Down Expand Up @@ -338,6 +339,11 @@ def set_api_key(api_key)
@api_key = api_key.to_s
end

def set_connection_options(base_url, ca_file)
@base_uri = URI.parse(base_url)
@ca_file = ca_file
end

def build_url(path, options)
path = scope_by_site(path, options)
query_params = map_array_params(options.fetch(:params, {}))
Expand Down
20 changes: 11 additions & 9 deletions lib/recurly/connection_pool.rb
Original file line number Diff line number Diff line change
@@ -1,36 +1,38 @@
# frozen_string_literal: true

require "net/https"

module Recurly
class ConnectionPool
def initialize
@mutex = Mutex.new
@pool = []
@pool = Hash.new { |h, k| h[k] = [] }
end

def with_connection
def with_connection(uri:, ca_file: nil)
http = nil
@mutex.synchronize do
http = @pool.pop
http = @pool[[uri.host, uri.port]].pop
end

# create connection if the pool was empty
http ||= init_http_connection
http ||= init_http_connection(uri, ca_file)

response = yield http

if http.started?
@mutex.synchronize do
@pool.push(http)
@pool[[uri.host, uri.port]].push(http)
end
end

response
end

def init_http_connection
http = Net::HTTP.new(Client::BASE_HOST, Client::BASE_PORT)
http.use_ssl = true
http.ca_file = Client::CA_FILE
def init_http_connection(uri, ca_file)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = uri.scheme == "https"
http.ca_file = ca_file
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
http.keep_alive_timeout = 600

Expand Down
4 changes: 3 additions & 1 deletion spec/recurly/client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
"recurly-total-records" => "3804",
}
end
let(:net_http) { Recurly::ConnectionPool.new.init_http_connection }
let(:net_http) {
Recurly::ConnectionPool.new.init_http_connection(URI.parse(Recurly::Client::BASE_URL), Recurly::Client::CA_FILE)
}
let(:connection_pool) {
pool = double("ConnectionPool")
allow(pool).to receive(:with_connection).and_yield net_http
Expand Down

0 comments on commit 7b660ce

Please sign in to comment.