Skip to content

Commit a4d906c

Browse files
committed
Add min/max_version for supporting adapters
1 parent 2fbd6b1 commit a4d906c

File tree

12 files changed

+127
-0
lines changed

12 files changed

+127
-0
lines changed

lib/httpi/adapter/curb.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,9 @@ def setup_ssl_auth
128128
when :SSLv23 then 2
129129
when :SSLv3 then 3
130130
end
131+
if ssl.min_version || ssl.max_version
132+
raise NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.'
133+
end
131134
end
132135

133136
def respond_with(client)

lib/httpi/adapter/excon.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ def client_opts
7373
end
7474

7575
opts[:ssl_version] = ssl.ssl_version if ssl.ssl_version
76+
opts[:ssl_min_version] = ssl.min_version if ssl.min_version
77+
opts[:ssl_max_version] = ssl.max_version if ssl.max_version
7678

7779
opts
7880
end

lib/httpi/adapter/http.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,8 @@ def create_client
5858
context.cert = @request.auth.ssl.cert
5959
context.key = @request.auth.ssl.cert_key
6060
context.ssl_version = @request.auth.ssl.ssl_version if @request.auth.ssl.ssl_version != nil
61+
context.min_version = @request.auth.ssl.min_version if @request.auth.ssl.min_version != nil
62+
context.max_version = @request.auth.ssl.max_version if @request.auth.ssl.max_version != nil
6163
context.verify_mode = @request.auth.ssl.openssl_verify_mode
6264

6365
client = ::HTTP::Client.new(:ssl_context => context)

lib/httpi/adapter/httpclient.rb

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,9 @@ def setup_ssl_auth
7878
end
7979

8080
@client.ssl_config.ssl_version = ssl.ssl_version.to_s if ssl.ssl_version
81+
if ssl.min_version || ssl.max_version
82+
raise NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead'
83+
end
8184
end
8285

8386
def respond_with(response)

lib/httpi/adapter/net_http.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,8 @@ def setup_ssl_auth
182182
end
183183

184184
@client.ssl_version = ssl.ssl_version if ssl.ssl_version
185+
@client.min_version = ssl.min_version if ssl.min_version
186+
@client.max_version = ssl.max_version if ssl.max_version
185187
end
186188

187189
def ssl_cert_store(ssl)

lib/httpi/auth/ssl.rb

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ class SSL
2020
ssl_context::METHODS.reject { |method| method.match(/server|client/) }
2121
end.sort.reverse
2222

23+
# Returns OpenSSL::SSL::*_VERSION values for min_version and max_version
24+
MIN_MAX_VERSIONS = OpenSSL::SSL.constants.select{|constant| constant =~/_VERSION$/}.map{|version| version.to_s.gsub(/_VERSION$/,'').to_sym}.reverse
25+
2326
# Returns whether SSL configuration is present.
2427
def present?
2528
(verify_mode == :none) || (cert && cert_key) || ca_cert_file
@@ -90,6 +93,36 @@ def ssl_version=(version)
9093
@ssl_version = version
9194
end
9295

96+
# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
97+
def min_version
98+
@min_version ||= nil
99+
end
100+
101+
# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::MIN_MAX_VERSIONS</tt>.
102+
def min_version=(version)
103+
unless MIN_MAX_VERSIONS.include? version
104+
raise ArgumentError, "Invalid SSL min_version #{version.inspect}\n" +
105+
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
106+
end
107+
108+
@min_version = version
109+
end
110+
111+
# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
112+
def max_version
113+
@max_version ||= nil
114+
end
115+
116+
# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::MIN_MAX_VERSIONS</tt>.
117+
def max_version=(version)
118+
unless MIN_MAX_VERSIONS.include? version
119+
raise ArgumentError, "Invalid SSL max_version #{version.inspect}\n" +
120+
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
121+
end
122+
123+
@max_version = version
124+
end
125+
93126
# Returns an <tt>OpenSSL::X509::Certificate</tt> for the +cert_file+.
94127
def cert
95128
@cert ||= (OpenSSL::X509::Certificate.new File.read(cert_file) if cert_file)

spec/httpi/adapter/curb_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -278,6 +278,16 @@
278278
adapter.request(:get)
279279
end
280280
end
281+
it 'raises error when min_version not nil' do
282+
request.auth.ssl.min_version = :TLS1_2
283+
expect{ adapter.request(:get) }.
284+
to raise_error(HTTPI::NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.')
285+
end
286+
it 'raises error when max_version not nil' do
287+
request.auth.ssl.max_version = :TLS1_2
288+
expect{ adapter.request(:get) }.
289+
to raise_error(HTTPI::NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.')
290+
end
281291
end
282292

283293
context "(for SSL client auth)" do

spec/httpi/adapter/httpclient_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,17 @@
178178

179179
adapter.request(:get)
180180
end
181+
182+
it 'raises error when min_version not nil' do
183+
request.auth.ssl.min_version = :TLS1_2
184+
expect{ adapter.request(:get) }.
185+
to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
186+
end
187+
it 'raises error when max_version not nil' do
188+
request.auth.ssl.max_version = :TLS1_2
189+
expect{ adapter.request(:get) }.
190+
to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
191+
end
181192
end
182193

183194
context "(for SSL client auth with a verify mode of :none with no certs provided)" do

spec/httpi/auth/ssl_spec.rb

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
describe HTTPI::Auth::SSL do
55
before(:all) do
66
@ssl_versions = HTTPI::Auth::SSL::SSL_VERSIONS
7+
@min_max_versions = HTTPI::Auth::SSL::MIN_MAX_VERSIONS
78
end
89

910
describe "VERIFY_MODES" do
@@ -158,6 +159,36 @@
158159
end
159160
end
160161

162+
describe "#min_version" do
163+
subject { HTTPI::Auth::SSL.new }
164+
165+
it "returns the min_version" do
166+
subject.min_version = @min_max_versions.first
167+
expect(subject.min_version).to eq(@min_max_versions.first)
168+
end
169+
170+
it 'raises ArgumentError if the version is unsupported' do
171+
expect { ssl.min_version = :ssl_fail }.
172+
to raise_error(ArgumentError, "Invalid SSL min_version :ssl_fail\n" +
173+
"Please specify one of #{@min_max_versions}")
174+
end
175+
end
176+
177+
describe "#max_version" do
178+
subject { HTTPI::Auth::SSL.new }
179+
180+
it "returns the SSL version" do
181+
subject.max_version = @min_max_versions.first
182+
expect(subject.max_version).to eq(@min_max_versions.first)
183+
end
184+
185+
it 'raises ArgumentError if the version is unsupported' do
186+
expect { ssl.max_version = :ssl_fail }.
187+
to raise_error(ArgumentError, "Invalid SSL max_version :ssl_fail\n" +
188+
"Please specify one of #{@min_max_versions}")
189+
end
190+
end
191+
161192
def ssl
162193
ssl = HTTPI::Auth::SSL.new
163194
ssl.cert_key_file = "spec/fixtures/client_key.pem"

spec/integration/excon_spec.rb

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,16 @@
129129
expect(response.body).to eq("get")
130130
end
131131

132+
it "works with min_version/max_version" do
133+
request = HTTPI::Request.new(@server.url)
134+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
135+
request.auth.ssl.min_version = :TLS1_2
136+
request.auth.ssl.max_version = :TLS1_2
137+
138+
response = HTTPI.get(request, adapter)
139+
expect(response.body).to eq("get")
140+
end
141+
132142
it "works with client cert and key provided as file path" do
133143
request = HTTPI::Request.new(@server.url)
134144
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file

0 commit comments

Comments
 (0)