Skip to content

Commit b2e93d6

Browse files
committed
Add a HTTP client for fiscalization
1 parent e404300 commit b2e93d6

File tree

1 file changed

+55
-0
lines changed

1 file changed

+55
-0
lines changed

lib/croatia/fiscalizer.rb

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# frozen_string_literal: true
22

33
require "digest/md5"
4+
require "net/http"
45
require "openssl"
56
require "securerandom"
67
require "tzinfo"
@@ -11,6 +12,60 @@ class Croatia::Fiscalizer
1112

1213
TZ = TZInfo::Timezone.get("Europe/Zagreb")
1314
QR_CODE_BASE_URL = "https://porezna.gov.hr/rn"
15+
DEFAULT_PORT = 443
16+
DEFAULT_TIMEOUT = 30
17+
USER_AGENT = "Croatia/#{Croatia::VERSION} Ruby/#{RUBY_VERSION} (Fiscalization Client; +https://github.com/monorkin/croatia)"
18+
19+
class << self
20+
attr_accessor :http_clients
21+
22+
def with_http_client_for(**options, &block)
23+
client = http_client_for(**options)
24+
retrying = false
25+
26+
begin
27+
block.call(client)
28+
rescue IOError, EOFError, Errno::ECONNRESET
29+
raise if retrying
30+
31+
retrying = true
32+
client.finish rescue nil
33+
client.start
34+
35+
retry
36+
end
37+
end
38+
39+
def http_client_for(host:, credential:, port: DEFAULT_PORT, timeout: DEFAULT_TIMEOUT)
40+
self.http_clients ||= {}
41+
42+
# MD5 is fast, but not cryptographically secure.
43+
# So the fingerprint is computed on less sensitive information.
44+
fingerprint = Digest::MD5.hexdigest("#{credential.certificate.serial}:#{credential.certificate.subject}")
45+
key = "#{host}:#{port}/#{fingerprint}?timeout=#{timeout}"
46+
47+
client = http_clients[key]
48+
49+
if client&.active?
50+
return client
51+
end
52+
53+
client&.finish rescue nil
54+
http_clients[key] = Net::HTTP.new(host, port).tap do |client|
55+
client.use_ssl = true
56+
client.verify_mode = OpenSSL::SSL::VERIFY_PEER
57+
client.cert = credential.certificate
58+
client.key = credential.key
59+
client.keep_alive_timeout = timeout
60+
client.start
61+
end
62+
end
63+
64+
def shutdown_all_clients
65+
http_clients&.each_value { |c| c.finish rescue nil }
66+
self.http_clients = {}
67+
end
68+
end
1469

1570
attr_reader :credential
1671

0 commit comments

Comments
 (0)