Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ AllCops:
- gemfile/**/*
Exclude:
- vendor/**/*
- spec/files/**/*

RSpec/SpecFilePathFormat:
Enabled: false
Expand Down
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
ezclient (1.7.1)
ezclient (1.7.2)
http (>= 4)

GEM
Expand Down
5 changes: 4 additions & 1 deletion lib/ezclient/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,12 @@ def request(verb, url, **options)

keep_alive_timeout = options.delete(:keep_alive)
api_auth = options.delete(:api_auth)
ssl_context = options[:ssl_context]

if keep_alive_timeout
client = persistent_client_registry.for(url, timeout: keep_alive_timeout)
client = persistent_client_registry.for(
url, ssl_context: ssl_context, timeout: keep_alive_timeout
)
else
client = HTTP::Client.new
end
Expand Down
22 changes: 18 additions & 4 deletions lib/ezclient/persistent_client_registry.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,31 @@ def initialize
self.registry = {}
end

def for(url, timeout:)
def for(url, ssl_context:, timeout:)
cleanup_registry!
uri = HTTP::URI.parse(url)
registry[uri.origin] ||= EzClient::PersistentClient.new(uri.origin, timeout)

origin = get_origin(url)
registry[origin] ||= {}

ssl_bucket = ssl_context&.cert ? get_cert_sha256(ssl_context.cert) : nil
registry[origin][ssl_bucket] ||= EzClient::PersistentClient.new(origin, timeout)
end

private

attr_accessor :registry

def get_cert_sha256(cert)
Digest::SHA256.hexdigest(cert.to_der)
end

def get_origin(url)
HTTP::URI.parse(url).origin
end

def cleanup_registry!
registry.delete_if { |_origin, client| client.timed_out? }
registry.each_value do |ssl_buckets|
ssl_buckets.delete_if { |_ssl_bucket, client| client.timed_out? }
end
end
end
2 changes: 1 addition & 1 deletion lib/ezclient/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module EzClient
VERSION = "1.7.1"
VERSION = "1.7.2"
end
19 changes: 19 additions & 0 deletions spec/files/cert1/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIUfinV8A6FiRyqX5ADPL13gzN5Q2YwDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwIbXl0ZXN0Q0EwHhcNMjUwNTE1MTIxODE4WhcNMjYwNTE1
MTIxODE4WjATMREwDwYDVQQDDAhteXRlc3RDQTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAKI5bLYi31jooJYjusgscCL0vcaH3pu1pyB3ajuLWjbjxaxf
h1u+JH3vTQaxaSaP9K7hSfjtd0QO4xaopmZKP/kFTgp8juC8HQhzUlz51syp2I72
AFKzmwnKiiQQh7mGHF2kWG5n8DjwY6F/7FohktTiUBBw1r/OypFGphVfz7iURNsU
/iOpwK63zSdqOoSgai35s1AmlTBB0eoldM/Ju6rSF0x712Y6bL2cK3dl1V3yG3sd
hXLkC9nOLnvOFUxyjXH/q4clvVblTP6IA+ez2EpIhkG4i+ZcEkIRY7YbH2GyFoxu
FS12fiLAi48zIbe1yz0nkrJZZTTw9o16A7+JHfECAwEAAaNTMFEwHQYDVR0OBBYE
FLyfG4zgydqWDtzyN1jpDBkn571MMB8GA1UdIwQYMBaAFLyfG4zgydqWDtzyN1jp
DBkn571MMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAE2Nzooz
PJbBi1vUGl9EkRPHuzZFHBR2YZvUQiIfH5TTigV3SeN2JoYacFqzcj8U7tFDoro5
i9VI89DJP+Kze2QADSkzR0o0mXb6HLDdJh+4/mGtWvkrMdhXW+Wr7i1x66jBmlrs
2ea+gTVcefyOhYm8LgD2V9mowQ8+iq+iOzbyYLd+rqnWzymQHz6trMZG7sy64OXk
tkzDH55eMjr34hi8mRlmfN/j7GAX+RnDVTI/kamIb8Yq/KJ0SmRIL8O5WdY2G85D
h5lU7YdnmBiDMqHOZbWSFT5L2vVUGEmAbl6dFpWgA/+mgb/OkeshKtfQWcINBDpH
Y6/1M+ULD7AFW4g=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions spec/files/cert1/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQCiOWy2It9Y6KCW
I7rILHAi9L3Gh96btacgd2o7i1o248WsX4dbviR9700GsWkmj/Su4Un47XdEDuMW
qKZmSj/5BU4KfI7gvB0Ic1Jc+dbMqdiO9gBSs5sJyookEIe5hhxdpFhuZ/A48GOh
f+xaIZLU4lAQcNa/zsqRRqYVX8+4lETbFP4jqcCut80najqEoGot+bNQJpUwQdHq
JXTPybuq0hdMe9dmOmy9nCt3ZdVd8ht7HYVy5AvZzi57zhVMco1x/6uHJb1W5Uz+
iAPns9hKSIZBuIvmXBJCEWO2Gx9hshaMbhUtdn4iwIuPMyG3tcs9J5KyWWU08PaN
egO/iR3xAgMBAAECggEAB6YfANh/QPKDrd3vPuR6K2pwRJs1QmYWhFKfwkElZrdR
zk6ZHoOGNh+ReW+7MOuyjQiyLkfzar9WnZkj8r3sqxnBBAAQVDrdFeqqwcJa9SlL
Uh75xWx9XSu9BzXLUdKnuueWmYASRNEFgEDR8gRUEhsTTNnRL605AmVly9YJwIlp
Ql/OMxdJFqmY8O8wEfyjYdWw7fk5JfqjAxcWwoZZjcXxrke8ue92hM1Z/pMDUBow
0pWousx6UVbbw4etjB6GjyPzA0esQYxXRjGcEAMznne41SAsfWAggnChhuNhV+lA
2GGRbCPLyck8Ce7K8UjY14bymUMMeVEpFXdedrh2lQKBgQDVfMbwrss4KNHwde0f
IBe4fQLQjBvelUBwDDgdQVHUygL6TWzsRKAmLV+A1HzPFuch5+FQK08fJImtE2Ci
xZPTAb5Nhs/S00W8UQLoH1L9O7g1nq7WxEKR08CJ8o7T+t3CMfqBlHLBx4jGf9HK
NrjErK3mGA9BPEeGH9rzCqhFlQKBgQDCh1e3+3CBnBePlsfv3RIo40Cm2s/OjUVU
jSawx14KZRtZUSa8bvU5J60AXDNsIG+9/kJuFm4fXNYCKo21l+jT271vxDrA5oFg
Lr+DoiojmE7M9ZteR3zkOEnvjr3aANTcTkQ7k+M+2iY6V4SsCNhXl0d3W2QA2xv+
zUG7Sssn7QKBgQCu+9BANLUjOeoiEzahfXeT4vtsnnq1bVZcwNc5u3FsXYwlR1MR
MYqm4CfYe9I1F8upMduvD2CR4SvrredWY2Wv3UzzVJ2Ba2RMX4ZnZk1qfQmXAZLD
PChoSM0XBLZnL8eWRcrTbS7GgFsugFQfT80Qf40l/PB8AwGJARFAhqq4JQKBgQCi
nIC3S3jA37rSTTjVSffkNhPVZxRPlche5Z9yJzZ1eg9imnPHEPnszT3RD0HtITBH
okPlwtpLXU+IgAn1wwbeEtJIm8CBgC6mOG3fm6+eEbPNoYI/TYMZQ/SKTMhndEp7
3vEq3HUaFUHfg0lkhgBTOCKFo9/01zSPywUni15IAQKBgQDNGWS0hKS46jzM7MYh
pwX5Dom/8QMbWuksRWX/bh5+5OhmPwH4aJTU8JFiMPrbtHoHfwcAYgrq746TiOd+
VH/VSr8YiaKjaPJG44sfsxhw/blrrhUUxOZi5RHxa2dTA83TVphFbG4sCFgRKNnl
bctg+wD5IZjsRbY1LHOY8tsqag==
-----END PRIVATE KEY-----
19 changes: 19 additions & 0 deletions spec/files/cert2/cert.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
-----BEGIN CERTIFICATE-----
MIIDBzCCAe+gAwIBAgIUUX0xpjoENDArPfJpKuvoP8Mq5KswDQYJKoZIhvcNAQEL
BQAwEzERMA8GA1UEAwwIbXl0ZXN0Q0EwHhcNMjUwNTE1MTIxOTA3WhcNMjYwNTE1
MTIxOTA3WjATMREwDwYDVQQDDAhteXRlc3RDQTCCASIwDQYJKoZIhvcNAQEBBQAD
ggEPADCCAQoCggEBAL212a7o5gL9wPf6jPqWN/nupPLaNJ8TQ0eqTpfkJw2Tk/Nu
fO7+e92xCUzIFr1F5p61i3QoNil7S1F11s5JtuDEhjUsoyiWyt4NGJYOyTkoeLf8
OAt1/vjypVLo8lqZHu5n9MaXW9BT4FyDVDcH8Bo2UKbP42PHdOOxllkhY4hyuC/o
zxpnT5nqiC6Lwblu4IdqLQA7J2u+4ZESS6tY1N7tvFJvrDfp36SESABgV3KVhct2
SAUZnwsM4lcIrx2Bt0FMU7Frwr3LpPl7Xg5tz93MPjDvlRwNStHoXm2ZGv6I6yIA
PbQEh0ut+Z7cbBAVOaTmXUjzk2/tIqnyDjyhyOsCAwEAAaNTMFEwHQYDVR0OBBYE
FL1iafEVzvkcSv+RnO/vT36uWvAFMB8GA1UdIwQYMBaAFL1iafEVzvkcSv+RnO/v
T36uWvAFMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBAEXLP+/k
1n/1S8AZOsmbaTiR+NBNCZx9JoGuqa5FZK/9cCchVd76bVPJLLu/mPBsLPHbNdhh
3XrP+s6NyvJd4QlHnk6OFxtqZB+wYY43dWtaoJxRc1bS6+xvhB6XQo5P/+5bLkzP
pc1Roc474SuldJ5im+D/xbEwGUHarpeKp/H1tKfYObUH3X0N6ZoyRLRePNNQceR9
2M/jZ878Rft2itTWE5SWvjexz2qK1mniyocEndvAWOh/4B4AV9jsXw2wxYJ6vH3l
EfFhPd+06DN6MvcsPsNenv0a+uOl9nyTq7kGxynSRRYlO0/l3DyKvQPQtxz6MlnN
ARcGd8jEg7SApA0=
-----END CERTIFICATE-----
28 changes: 28 additions & 0 deletions spec/files/cert2/key.pem
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
-----BEGIN PRIVATE KEY-----
MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQC9tdmu6OYC/cD3
+oz6ljf57qTy2jSfE0NHqk6X5CcNk5Pzbnzu/nvdsQlMyBa9ReaetYt0KDYpe0tR
ddbOSbbgxIY1LKMolsreDRiWDsk5KHi3/DgLdf748qVS6PJamR7uZ/TGl1vQU+Bc
g1Q3B/AaNlCmz+Njx3TjsZZZIWOIcrgv6M8aZ0+Z6ogui8G5buCHai0AOydrvuGR
EkurWNTe7bxSb6w36d+khEgAYFdylYXLdkgFGZ8LDOJXCK8dgbdBTFOxa8K9y6T5
e14Obc/dzD4w75UcDUrR6F5tmRr+iOsiAD20BIdLrfme3GwQFTmk5l1I85Nv7SKp
8g48ocjrAgMBAAECggEAJ3HYrZwCOyv8w/LF/lJemCptBIunNk4ghpWcGsvW7OU6
9XoLIvwp0An/14Wg6MDQdz5jHQdBX7WhjvHz9FdyXWCvUP4TfJyB2NKbQpQXdbl7
BDI+iu+BUMzO4CLMRVciDcryo5oT/oh6FXI+/+Q4IZMaiNyfuH7fyHoDu0uMcPGh
ncgPCoFh8+9wauvg/LrY1XBxk66nUvL4IivQN/7uDTIG2mo2BR8+ai2wg3EosvPj
bn36leJsWnZ0ZWHzbfsSqGA1A6U5m1RBQKLij3YUJbkaGiQ1KfqHXso1JCnMhpwM
NCD5qVXLZO4Fa6N4iNgRVSTrmi1ACLyiXFac3qi3uQKBgQDpGR9ri7uf2UI+bC1y
8PNso3AD2pqXS/hvwHNBRqjoRRZeVG5SdLZXZhKyANhsOWZ7+9Co3TAhuzZ6PBty
y6eJzDnqoURUAkMGPYPIX9Vhvh/O25MSw50jrKxfAoyS/RLI27akto262g98GC0E
48jXz8rReCgYbgnmmm6qBKifWQKBgQDQWXB7rbLdKfqYrSSa/YCGIvu6qKIrTVsr
ciSPsxKmC1dLuRf4p/InLGDL1GIuwqCR4xVuPMGI3jL0JV2fXZzh9CFiuaxfm6oM
wwwWQNIh1XEXHWh4f2Of97GC32gpMwBOSfwzDknf8MB1vGYmSVdNrfNucyd54WIS
m5bLYcXF4wKBgQC3kSRQUoOYl8T2WcTU/vIEvRUqw834lkh44Usivd2oxTefY8hZ
wTYTz/urGMVXPUD7JM0nHsGX3tJBIvLOzZkMCLwXjZa8vedAk9MjSm1Fgy+TfRHu
tgQbIxG/5McFvq07ZuQIBQfKfY2yQWu6rRPu+OIVYhXZX1cGttmtpOuSSQKBgQDJ
ZywM4oQctw+/tt/D03oCMJ8WeR0KruSKwvQE1R4Z1Ky2Tl6VyAOVSpjncI7YlNuT
Kuj0f1a2b9ThnZ07CMs2wT/kp4exhFCFtaZhfJekjSedKJhsovgzEsVNtZiC+wI4
q9xXnmBbUec56Lz2Fb+HH7hJ9JccgnrDchP61rDP8QKBgGM0ydfyQEybl+oWhPCN
kUGxon6cZ8GZXpZQ9ocvQo+4sqJtQ6cBE+oNE0oCXnaSMXHNhRdOyR3ALCXUO5tK
mjAQA6JFKWyb3DUoiDH6jEyq8FB2Fqe7VAio/Gbfxb+eOlttCU4FA+hZDRd21OiM
n61wVEHtyOKDrutOQbRuDtRw
-----END PRIVATE KEY-----
2 changes: 0 additions & 2 deletions spec/files/file.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
# frozen_string_literal: true

hello
world
36 changes: 36 additions & 0 deletions spec/persistent_connections_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,19 @@
WebMock.enable!
end

before { GC.start }

def read_file(path)
File.new("#{__dir__}/files/#{path}").read
end

def make_ssl_context(cert, key)
OpenSSL::SSL::SSLContext.new.tap do |ssl_context|
ssl_context.cert = OpenSSL::X509::Certificate.new(cert)
ssl_context.key = OpenSSL::PKey.read(key)
end
end

it "removes connections that are timed out on each request" do
client = EzClient.new(keep_alive: 1, timeout: 15)

Expand All @@ -27,4 +40,27 @@
connection_count = ObjectSpace.each_object(HTTP::Connection).count
expect(connection_count).to eq(1)
end

it "boots up separate http connections for different ssl contexts" do
client = EzClient.new(keep_alive: 15)

cert1 = read_file("cert1/cert.pem")
key1 = read_file("cert1/key.pem")
cert2 = read_file("cert2/cert.pem")
key2 = read_file("cert2/key.pem")

ssl_context1 = make_ssl_context(cert1, key1)
ssl_context2 = make_ssl_context(cert2, key2)

2.times do
client.perform!(:get, "https://ya.ru", ssl_context: ssl_context1)
end

2.times do
client.perform!(:get, "https://ya.ru", ssl_context: ssl_context2)
end

connection_count = ObjectSpace.each_object(HTTP::Connection).count
expect(connection_count).to eq(2)
end
end