diff --git a/README.md b/README.md index 77d6f4a..5d3fbaf 100644 --- a/README.md +++ b/README.md @@ -124,6 +124,25 @@ You can choose to configure some default values like this e = Epics::Client.new(keys, 'passphrase', 'url', 'host', 'user', 'partner', locale: :fr, product_name: 'Mon Epic Client EBICS') ``` +#### Timeout Configuration + +You can configure custom timeout values for HTTP requests: + +```ruby +e = Epics::Client.new( + keys, + 'passphrase', + 'url', + 'host', + 'user', + 'partner', + timeout: 120, # Request timeout in seconds (default: nil - uses Faraday default) + open_timeout: 30 # Connection timeout in seconds (default: nil - uses Faraday default) +) +``` + +This is useful when dealing with slow bank servers or network conditions that require longer timeouts. + ## Features ### Initialization diff --git a/lib/epics/client.rb b/lib/epics/client.rb index c71bc30..37585f4 100644 --- a/lib/epics/client.rb +++ b/lib/epics/client.rb @@ -1,8 +1,8 @@ class Epics::Client extend Forwardable - attr_accessor :passphrase, :url, :host_id, :user_id, :partner_id, :keys, :keys_content, :locale, :product_name, - :x_509_certificates_content, :debug_mode + attr_accessor :passphrase, :url, :host_id, :user_id, :partner_id, :keys, :keys_content, :timeout, :open_timeout, + :locale, :product_name, :x_509_certificates_content, :debug_mode attr_writer :iban, :bic, :name @@ -16,14 +16,16 @@ def initialize(keys_content, passphrase, url, host_id, user_id, partner_id, opti self.host_id = host_id self.user_id = user_id self.partner_id = partner_id + self.timeout = options[:timeout] + self.open_timeout = options[:open_timeout] self.locale = options[:locale] || Epics::DEFAULT_LOCALE self.product_name = options[:product_name] || Epics::DEFAULT_PRODUCT_NAME - self.debug_mode = !!options[:debug_mode] self.x_509_certificates_content = { a: options[:x_509_certificate_a_content], x: options[:x_509_certificate_x_content], e: options[:x_509_certificate_e_content] } + self.debug_mode = !!options[:debug_mode] end def inspect @@ -338,11 +340,22 @@ def download_and_unzip(order_type, *args, **options) end def connection - @connection ||= Faraday.new(headers: { 'Content-Type' => 'text/xml', user_agent: "EPICS v#{Epics::VERSION}"}, ssl: { verify: verify_ssl? }) do |faraday| - faraday.use Epics::XMLSIG, { client: self } - faraday.use Epics::ParseEbics, { client: self} - # faraday.use MyAdapter - faraday.response :logger, ::Logger.new(STDOUT), bodies: true if debug_mode # log requests/response to STDOUT + @connection ||= begin + connection_options = { + headers: { 'Content-Type' => 'text/xml', user_agent: "EPICS v#{Epics::VERSION}"}, + ssl: { verify: verify_ssl? } + } + + request_options = {} + request_options[:timeout] = timeout if timeout + request_options[:open_timeout] = open_timeout if open_timeout + connection_options[:request] = request_options unless request_options.empty? + + Faraday.new(connection_options) do |faraday| + faraday.use Epics::XMLSIG, { client: self } + faraday.use Epics::ParseEbics, { client: self} + faraday.response :logger, ::Logger.new(STDOUT), bodies: true if debug_mode + end end end diff --git a/spec/client_spec.rb b/spec/client_spec.rb index d3c2c8d..2d3d332 100644 --- a/spec/client_spec.rb +++ b/spec/client_spec.rb @@ -48,6 +48,49 @@ end end + context 'timeout configuration' do + let(:client_with_timeouts) do + described_class.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS', + timeout: 60, open_timeout: 10) + end + + let(:client_without_timeouts) do + described_class.new(key, 'secret', 'https://194.180.18.30/ebicsweb/ebicsweb', 'SIZBN001', 'EBIX', 'EBICS') + end + + it 'accepts timeout option' do + expect(client_with_timeouts.timeout).to eq(60) + end + + it 'accepts open_timeout option' do + expect(client_with_timeouts.open_timeout).to eq(10) + end + + it 'allows nil timeout when not specified' do + expect(client_without_timeouts.timeout).to be_nil + end + + it 'allows nil open_timeout when not specified' do + expect(client_without_timeouts.open_timeout).to be_nil + end + + it 'applies timeout to Faraday connection when specified' do + connection = client_with_timeouts.send(:connection) + expect(connection.options.timeout).to eq(60) + end + + it 'applies open_timeout to Faraday connection when specified' do + connection = client_with_timeouts.send(:connection) + expect(connection.options.open_timeout).to eq(10) + end + + it 'does not set request options when timeouts are not specified' do + connection = client_without_timeouts.send(:connection) + expect(connection.options.timeout).to be_nil + expect(connection.options.open_timeout).to be_nil + end + end + describe '#inspect' do it 'will not print the complete object' do expect(subject.inspect).to include("@keys=#{subject.keys.keys}")