httpi 2.4.4 → 3.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/development.yml +48 -0
- data/CHANGELOG.md +20 -0
- data/Gemfile +8 -6
- data/README.md +14 -15
- data/UPDATING.md +7 -0
- data/httpi.gemspec +5 -6
- data/lib/httpi/adapter/curb.rb +4 -0
- data/lib/httpi/adapter/excon.rb +4 -0
- data/lib/httpi/adapter/http.rb +3 -0
- data/lib/httpi/adapter/httpclient.rb +4 -0
- data/lib/httpi/adapter/net_http.rb +3 -2
- data/lib/httpi/adapter/net_http_persistent.rb +5 -2
- data/lib/httpi/auth/ssl.rb +52 -1
- data/lib/httpi/version.rb +1 -1
- data/spec/fixtures/client_cert.pem +18 -14
- data/spec/fixtures/client_key.pem +25 -13
- data/spec/httpi/adapter/curb_spec.rb +17 -0
- data/spec/httpi/adapter/em_http_spec.rb +2 -8
- data/spec/httpi/adapter/excon_spec.rb +6 -0
- data/spec/httpi/adapter/httpclient_spec.rb +18 -0
- data/spec/httpi/auth/ssl_spec.rb +48 -0
- data/spec/httpi/httpi_spec.rb +2 -4
- data/spec/integration/curb_spec.rb +9 -0
- data/spec/integration/em_http_spec.rb +2 -2
- data/spec/integration/excon_spec.rb +20 -1
- data/spec/integration/fixtures/ca_all.pem +17 -42
- data/spec/integration/fixtures/server.cert +17 -17
- data/spec/integration/fixtures/server.key +25 -13
- data/spec/integration/http_spec.rb +19 -0
- data/spec/integration/httpclient_spec.rb +9 -0
- data/spec/integration/net_http_persistent_spec.rb +13 -2
- data/spec/integration/net_http_spec.rb +30 -3
- data/spec/integration/support/server.rb +1 -2
- data/spec/spec_helper.rb +0 -2
- metadata +15 -29
- data/.travis.yml +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c3e533863eed443ec1b23c42cf9959c3312c8ddff5a1b45102028263325ad473
|
4
|
+
data.tar.gz: 5ea0350ab1711603f712d0ae02ea6e14f3f89b225866585b5aff8833c855d60c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3d53e35db56687d59d42e7b7e2b609c00ec3f5d241a77189bcbd780c87d6596466a0e709d300ed66956e67634f228c94dff675bd60ec13b6c5a4d1422f5253d1
|
7
|
+
data.tar.gz: 29fa0caf340530e89c435c1730387d255301ad6a06395b8860c1642c272150c91ce0f5c7c128a5500aecf0ba5484fbeaed384600f60ce48a530dd51b76e8b690
|
@@ -0,0 +1,48 @@
|
|
1
|
+
name: Development
|
2
|
+
|
3
|
+
on: [push, pull_request]
|
4
|
+
|
5
|
+
jobs:
|
6
|
+
test:
|
7
|
+
name: ${{matrix.ruby}} on ${{matrix.os}}
|
8
|
+
runs-on: ${{matrix.os}}-latest
|
9
|
+
continue-on-error: ${{matrix.experimental}}
|
10
|
+
|
11
|
+
strategy:
|
12
|
+
matrix:
|
13
|
+
os:
|
14
|
+
- ubuntu
|
15
|
+
|
16
|
+
ruby:
|
17
|
+
- "2.6"
|
18
|
+
- "2.7"
|
19
|
+
- "3.0"
|
20
|
+
|
21
|
+
experimental: [false]
|
22
|
+
env: [""]
|
23
|
+
|
24
|
+
include:
|
25
|
+
- os: ubuntu
|
26
|
+
ruby: truffleruby
|
27
|
+
experimental: true
|
28
|
+
- os: ubuntu
|
29
|
+
ruby: jruby
|
30
|
+
experimental: true
|
31
|
+
- os: ubuntu
|
32
|
+
ruby: head
|
33
|
+
experimental: true
|
34
|
+
|
35
|
+
steps:
|
36
|
+
- uses: actions/checkout@v2
|
37
|
+
|
38
|
+
- name: Install dependencies
|
39
|
+
run: sudo apt-get install libcurl4-openssl-dev
|
40
|
+
|
41
|
+
- uses: ruby/setup-ruby@v1
|
42
|
+
with:
|
43
|
+
ruby-version: ${{matrix.ruby}}
|
44
|
+
bundler-cache: true
|
45
|
+
|
46
|
+
- name: Run tests
|
47
|
+
timeout-minutes: 5
|
48
|
+
run: ${{matrix.env}} bundle exec rspec
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,23 @@
|
|
1
|
+
### 3.0.1 (2021-12-17)
|
2
|
+
|
3
|
+
* Fix: [#230](https://github.com/savonrb/httpi/pull/230) Make rack a runtime dependency.
|
4
|
+
|
5
|
+
### 3.0.0 (2021-10-19)
|
6
|
+
|
7
|
+
* Improvement: [#225](https://github.com/savonrb/httpi/pull/225) Make rack and socksify dependencies optional.
|
8
|
+
|
9
|
+
### 2.5.0 (2021-10-05)
|
10
|
+
|
11
|
+
* Feature: [#214](https://github.com/savonrb/httpi/pull/214) Add SSL ciphers configuration
|
12
|
+
* Improvement: [#227](https://github.com/savonrb/httpi/pull/227) Use GitHub Actions as CI. Require at least Ruby v2.3.
|
13
|
+
|
14
|
+
### 2.4.5
|
15
|
+
|
16
|
+
* Improvement: [#209](https://github.com/savonrb/httpi/pull/209) Drop Travis CI support for Ruby < 2.3.0 and jruby.
|
17
|
+
* Feature: [#208](https://github.com/savonrb/httpi/pull/208) Add SSL min/max_version configuration for supporting adapters
|
18
|
+
* Improvement: [#206](https://github.com/savonrb/httpi/pull/206) Support for net-http-persistent v3
|
19
|
+
* Improvement: [#204](https://github.com/savonrb/httpi/pull/204) Avoid excon warning
|
20
|
+
|
1
21
|
### 2.4.4
|
2
22
|
|
3
23
|
* Improvement: [#197](https://github.com/savonrb/httpi/pull/197) Add support for new write timeout option to all adapters
|
data/Gemfile
CHANGED
@@ -3,18 +3,20 @@ gemspec
|
|
3
3
|
|
4
4
|
gem 'jruby-openssl', :platforms => :jruby
|
5
5
|
|
6
|
-
|
7
|
-
gem 'public_suffix', '~> 2.0' # or remove rubies < 2.1 from travis.yml
|
6
|
+
gem 'public_suffix', '~> 4.0'
|
8
7
|
|
9
8
|
# http clients
|
10
9
|
gem 'httpclient', '~> 2.3', :require => false
|
11
|
-
gem 'curb', '~> 0.8', :require => false, :platforms => :ruby
|
12
|
-
gem 'em-http-request', :require => false, :platforms => [:ruby
|
10
|
+
gem 'curb', '~> 0.8', :require => false, :platforms => [:ruby]
|
11
|
+
gem 'em-http-request', :require => false, :platforms => [:ruby]
|
13
12
|
gem 'em-synchrony', :require => false, :platforms => [:ruby, :jruby]
|
14
13
|
gem 'excon', '~> 0.21', :require => false, :platforms => [:ruby, :jruby]
|
15
|
-
gem 'net-http-persistent', '~>
|
14
|
+
gem 'net-http-persistent', '~> 4.0', :require => false
|
16
15
|
gem 'http', :require => false
|
17
16
|
|
17
|
+
# adapter extensions
|
18
|
+
gem 'rack'
|
19
|
+
gem 'socksify'
|
20
|
+
|
18
21
|
# coverage
|
19
22
|
gem 'simplecov', :require => false
|
20
|
-
gem 'coveralls', :require => false
|
data/README.md
CHANGED
@@ -2,33 +2,22 @@
|
|
2
2
|
|
3
3
|
A common interface for Ruby's HTTP libraries.
|
4
4
|
|
5
|
-
[Documentation](https://www.rubydoc.info/gems/httpi)
|
6
|
-
[Mailing list](https://groups.google.com/forum/#!forum/httpirb)
|
7
|
-
|
8
|
-
[![Build Status](https://secure.travis-ci.org/savonrb/httpi.png?branch=master)](http://travis-ci.org/savonrb/httpi)
|
9
|
-
[![Gem Version](https://badge.fury.io/rb/httpi.png)](http://badge.fury.io/rb/httpi)
|
10
|
-
[![Code Climate](https://codeclimate.com/github/savonrb/httpi.png)](https://codeclimate.com/github/savonrb/httpi)
|
11
|
-
[![Coverage Status](https://coveralls.io/repos/savonrb/httpi/badge.png?branch=master)](https://coveralls.io/r/savonrb/httpi)
|
5
|
+
[Documentation](https://www.rubydoc.info/gems/httpi)
|
12
6
|
|
7
|
+
[![Development](https://github.com/savonrb/httpi/actions/workflows/development.yml/badge.svg)](https://github.com/savonrb/httpi/actions/workflows/development.yml)
|
13
8
|
|
14
9
|
## Installation
|
15
10
|
|
16
11
|
HTTPI is available through [Rubygems](https://rubygems.org/gems/httpi) and can be installed via:
|
17
12
|
|
18
|
-
|
19
|
-
$ gem install httpi
|
20
|
-
```
|
13
|
+
$ gem install httpi
|
21
14
|
|
22
15
|
or add it to your Gemfile like this:
|
23
16
|
|
24
|
-
|
25
|
-
gem 'httpi', '~> 2.1.0'
|
26
|
-
```
|
27
|
-
|
17
|
+
gem 'httpi', '~> 3.0.0'
|
28
18
|
|
29
19
|
## Usage example
|
30
20
|
|
31
|
-
|
32
21
|
``` ruby
|
33
22
|
require "httpi"
|
34
23
|
|
@@ -49,6 +38,16 @@ HTTPI.adapter = :httpclient
|
|
49
38
|
HTTPI.request(:custom, request)
|
50
39
|
```
|
51
40
|
|
41
|
+
### SOCKS Proxy Support
|
42
|
+
|
43
|
+
To use the the SOCKS proxy support, please add the `socksify` gem to your gemfile, and add the following code:
|
44
|
+
|
45
|
+
``` ruby
|
46
|
+
require 'socksify'
|
47
|
+
require 'socksify/http'
|
48
|
+
```
|
49
|
+
|
50
|
+
to your project.
|
52
51
|
|
53
52
|
## Documentation
|
54
53
|
|
data/UPDATING.md
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
# Update guide
|
2
|
+
|
3
|
+
## From 2.x to 3.x
|
4
|
+
|
5
|
+
BREAKING CHANGE: the [#255](https://github.com/savonrb/httpi/pull/225) made the gem socksify and rack gems optional dependencies.
|
6
|
+
|
7
|
+
In order to restore the old behavior, see the README section "SOCKS Proxy Support" and "Rack Mock Adapter".
|
data/httpi.gemspec
CHANGED
@@ -11,19 +11,18 @@ Gem::Specification.new do |s|
|
|
11
11
|
s.homepage = "http://github.com/savonrb/#{s.name}"
|
12
12
|
s.summary = "Common interface for Ruby's HTTP libraries"
|
13
13
|
s.description = s.summary
|
14
|
-
s.required_ruby_version = '>= 1.9.2'
|
15
14
|
|
16
|
-
s.
|
15
|
+
s.required_ruby_version = '>= 2.3'
|
16
|
+
|
17
17
|
s.license = 'MIT'
|
18
18
|
|
19
19
|
s.add_dependency 'rack'
|
20
|
-
s.add_dependency 'socksify'
|
21
20
|
|
22
21
|
s.add_development_dependency 'rubyntlm', '~> 0.3.2'
|
23
|
-
s.add_development_dependency 'rake', '~>
|
24
|
-
s.add_development_dependency 'rspec', '~>
|
22
|
+
s.add_development_dependency 'rake', '~> 13.0'
|
23
|
+
s.add_development_dependency 'rspec', '~> 3.5'
|
25
24
|
s.add_development_dependency 'mocha', '~> 0.13'
|
26
|
-
s.add_development_dependency 'puma', '~>
|
25
|
+
s.add_development_dependency 'puma', '~> 5.0'
|
27
26
|
s.add_development_dependency 'webmock'
|
28
27
|
|
29
28
|
s.files = `git ls-files`.split("\n")
|
data/lib/httpi/adapter/curb.rb
CHANGED
@@ -116,6 +116,7 @@ module HTTPI
|
|
116
116
|
@client.cert_key = ssl.cert_key_file
|
117
117
|
@client.cert = ssl.cert_file
|
118
118
|
@client.certpassword = ssl.cert_key_password
|
119
|
+
@client.set(:ssl_cipher_list, ssl.ciphers.join(':')) if ssl.ciphers
|
119
120
|
|
120
121
|
@client.ssl_verify_peer = ssl.verify_mode == :peer
|
121
122
|
end
|
@@ -128,6 +129,9 @@ module HTTPI
|
|
128
129
|
when :SSLv23 then 2
|
129
130
|
when :SSLv3 then 3
|
130
131
|
end
|
132
|
+
if ssl.min_version || ssl.max_version
|
133
|
+
raise NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.'
|
134
|
+
end
|
131
135
|
end
|
132
136
|
|
133
137
|
def respond_with(client)
|
data/lib/httpi/adapter/excon.rb
CHANGED
@@ -41,6 +41,7 @@ module HTTPI
|
|
41
41
|
|
42
42
|
opts = {
|
43
43
|
:host => url.host,
|
44
|
+
:hostname => url.hostname,
|
44
45
|
:path => url.path,
|
45
46
|
:port => url.port,
|
46
47
|
:query => url.query,
|
@@ -72,7 +73,10 @@ module HTTPI
|
|
72
73
|
opts[:ssl_verify_peer] = false
|
73
74
|
end
|
74
75
|
|
76
|
+
opts[:ciphers] = ssl.ciphers if ssl.ciphers
|
75
77
|
opts[:ssl_version] = ssl.ssl_version if ssl.ssl_version
|
78
|
+
opts[:ssl_min_version] = ssl.min_version if ssl.min_version
|
79
|
+
opts[:ssl_max_version] = ssl.max_version if ssl.max_version
|
76
80
|
|
77
81
|
opts
|
78
82
|
end
|
data/lib/httpi/adapter/http.rb
CHANGED
@@ -58,7 +58,10 @@ module HTTPI
|
|
58
58
|
context.cert = @request.auth.ssl.cert
|
59
59
|
context.key = @request.auth.ssl.cert_key
|
60
60
|
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
|
61
63
|
context.verify_mode = @request.auth.ssl.openssl_verify_mode
|
64
|
+
context.ciphers = @request.auth.ssl.ciphers if @request.auth.ssl.ciphers
|
62
65
|
|
63
66
|
client = ::HTTP::Client.new(:ssl_context => context)
|
64
67
|
else
|
@@ -73,11 +73,15 @@ module HTTPI
|
|
73
73
|
# Send client-side certificate regardless of state of SSL verify mode
|
74
74
|
@client.ssl_config.client_cert = ssl.cert
|
75
75
|
@client.ssl_config.client_key = ssl.cert_key
|
76
|
+
@client.ssl_config.ciphers = ssl.ciphers if ssl.ciphers
|
76
77
|
|
77
78
|
@client.ssl_config.verify_mode = ssl.openssl_verify_mode
|
78
79
|
end
|
79
80
|
|
80
81
|
@client.ssl_config.ssl_version = ssl.ssl_version.to_s if ssl.ssl_version
|
82
|
+
if ssl.min_version || ssl.max_version
|
83
|
+
raise NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead'
|
84
|
+
end
|
81
85
|
end
|
82
86
|
|
83
87
|
def respond_with(response)
|
@@ -4,8 +4,6 @@ require "httpi/adapter/base"
|
|
4
4
|
require "httpi/response"
|
5
5
|
require 'kconv'
|
6
6
|
require 'socket'
|
7
|
-
require "socksify"
|
8
|
-
require 'socksify/http'
|
9
7
|
|
10
8
|
module HTTPI
|
11
9
|
module Adapter
|
@@ -177,11 +175,14 @@ module HTTPI
|
|
177
175
|
# Send client-side certificate regardless of state of SSL verify mode
|
178
176
|
@client.key = ssl.cert_key
|
179
177
|
@client.cert = ssl.cert
|
178
|
+
@client.ciphers = ssl.ciphers if ssl.ciphers
|
180
179
|
|
181
180
|
@client.verify_mode = ssl.openssl_verify_mode
|
182
181
|
end
|
183
182
|
|
184
183
|
@client.ssl_version = ssl.ssl_version if ssl.ssl_version
|
184
|
+
@client.min_version = ssl.min_version if ssl.min_version
|
185
|
+
@client.max_version = ssl.max_version if ssl.max_version
|
185
186
|
end
|
186
187
|
|
187
188
|
def ssl_cert_store(ssl)
|
@@ -12,7 +12,11 @@ module HTTPI
|
|
12
12
|
private
|
13
13
|
|
14
14
|
def create_client
|
15
|
-
Net::HTTP::Persistent.new
|
15
|
+
if Gem::Version.new(Net::HTTP::Persistent::VERSION) >= Gem::Version.new('3.0.0')
|
16
|
+
Net::HTTP::Persistent.new name: thread_key
|
17
|
+
else
|
18
|
+
Net::HTTP::Persistent.new thread_key
|
19
|
+
end
|
16
20
|
end
|
17
21
|
|
18
22
|
def perform(http, http_request, &on_body)
|
@@ -38,7 +42,6 @@ module HTTPI
|
|
38
42
|
def thread_key
|
39
43
|
@request.url.host.split(/\W/).reject{|p|p == ""}.join('-')
|
40
44
|
end
|
41
|
-
|
42
45
|
end
|
43
46
|
end
|
44
47
|
end
|
data/lib/httpi/auth/ssl.rb
CHANGED
@@ -20,9 +20,12 @@ module HTTPI
|
|
20
20
|
ssl_context::METHODS.reject { |method| method.match(/server|client/) }
|
21
21
|
end.sort.reverse
|
22
22
|
|
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
|
+
|
23
26
|
# Returns whether SSL configuration is present.
|
24
27
|
def present?
|
25
|
-
(verify_mode == :none) || (cert && cert_key) || ca_cert_file
|
28
|
+
(verify_mode == :none) || (cert && cert_key) || ca_cert_file || ciphers
|
26
29
|
rescue TypeError, Errno::ENOENT
|
27
30
|
false
|
28
31
|
end
|
@@ -45,6 +48,24 @@ module HTTPI
|
|
45
48
|
# Certificate store holds trusted CA certificates used to verify peer certificates.
|
46
49
|
attr_accessor :cert_store
|
47
50
|
|
51
|
+
# Accessor for the SSL ciphers list.
|
52
|
+
attr_reader :ciphers
|
53
|
+
|
54
|
+
# Sets the available symmetric algorithms for encryption and decryption.
|
55
|
+
# @see OpenSSL::SSL::SSLContext#ciphers
|
56
|
+
# @example
|
57
|
+
# ssl.ciphers = "cipher1:cipher2:..."
|
58
|
+
# ssl.ciphers = [name, ...]
|
59
|
+
# ssl.ciphers = [[name, version, bits, alg_bits], ...]
|
60
|
+
def ciphers=(ciphers)
|
61
|
+
@ciphers =
|
62
|
+
if ciphers
|
63
|
+
context = OpenSSL::SSL::SSLContext.new
|
64
|
+
context.ciphers = ciphers
|
65
|
+
context.ciphers.map(&:first)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
48
69
|
# Returns the cert type to validate SSL certificates PEM|DER.
|
49
70
|
def cert_type
|
50
71
|
@cert_type ||= :pem
|
@@ -90,6 +111,36 @@ module HTTPI
|
|
90
111
|
@ssl_version = version
|
91
112
|
end
|
92
113
|
|
114
|
+
# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
|
115
|
+
def min_version
|
116
|
+
@min_version ||= nil
|
117
|
+
end
|
118
|
+
|
119
|
+
# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::MIN_MAX_VERSIONS</tt>.
|
120
|
+
def min_version=(version)
|
121
|
+
unless MIN_MAX_VERSIONS.include? version
|
122
|
+
raise ArgumentError, "Invalid SSL min_version #{version.inspect}\n" +
|
123
|
+
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
|
124
|
+
end
|
125
|
+
|
126
|
+
@min_version = version
|
127
|
+
end
|
128
|
+
|
129
|
+
# Returns the SSL min_version number. Defaults to <tt>nil</tt> (auto-negotiate).
|
130
|
+
def max_version
|
131
|
+
@max_version ||= nil
|
132
|
+
end
|
133
|
+
|
134
|
+
# Sets the SSL min_version number. Expects one of <tt>HTTPI::Auth::SSL::MIN_MAX_VERSIONS</tt>.
|
135
|
+
def max_version=(version)
|
136
|
+
unless MIN_MAX_VERSIONS.include? version
|
137
|
+
raise ArgumentError, "Invalid SSL max_version #{version.inspect}\n" +
|
138
|
+
"Please specify one of #{MIN_MAX_VERSIONS.inspect}"
|
139
|
+
end
|
140
|
+
|
141
|
+
@max_version = version
|
142
|
+
end
|
143
|
+
|
93
144
|
# Returns an <tt>OpenSSL::X509::Certificate</tt> for the +cert_file+.
|
94
145
|
def cert
|
95
146
|
@cert ||= (OpenSSL::X509::Certificate.new File.read(cert_file) if cert_file)
|
data/lib/httpi/version.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
2
|
+
MIIDVTCCAj2gAwIBAgIBATANBgkqhkiG9w0BAQsFADAjMSEwHwYDVQQKDBhEZXZl
|
3
|
+
bG9wbWVudC9DTj1sb2NhbGhvc3QwHhcNMTgwODEwMDAzMTQzWhcNMjgwODA3MDAz
|
4
|
+
MTQzWjAjMSEwHwYDVQQKDBhEZXZlbG9wbWVudC9DTj1sb2NhbGhvc3QwggEiMA0G
|
5
|
+
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDbU3vifU9omTx5T6ECuYnvryr4iWPP
|
6
|
+
A4sXhduO8aD3IdA8zHlPtZnmh0liE30nAY00xKa4Eisxs9/UgUoHlEb5nCtYs6Od
|
7
|
+
9pjiuyry2G5lBHIhLlVNTbReRKfjhr3ewUxcnQN0xiynjfsUMbzoVI1ZsGDWZ9gF
|
8
|
+
4DHg3Accee3+/BNBDTWixYXh64D9YI1Tj/3fC1I2taUp32jdLXE9mbCByQlk5EZf
|
9
|
+
BZUWx868FtwwzU3ymbq2uQQtTl5a0QHqLUwb0nkdewoRvaZJFkopI+1tgy0Hs+pY
|
10
|
+
QM99vQWS7ViM5qbVYtPil/4VVWJbx/kQi/To4/Q8TxYbIRkoeJSOq9U3AgMBAAGj
|
11
|
+
gZMwgZAwDAYDVR0TAQH/BAIwADAdBgNVHQ4EFgQU4W1eb4Zc4NOpBe8UXcmIzLHB
|
12
|
+
FFQwSwYDVR0jBEQwQoAU4W1eb4Zc4NOpBe8UXcmIzLHBFFShJ6QlMCMxITAfBgNV
|
13
|
+
BAoMGERldmVsb3BtZW50L0NOPWxvY2FsaG9zdIIBATAUBgNVHREEDTALgglsb2Nh
|
14
|
+
bGhvc3QwDQYJKoZIhvcNAQELBQADggEBAM7oYR6eVIascNLhgfJFboVernRl137Y
|
15
|
+
7hyjBQTSleMame/VN1MwMscUYpen8rFu9lUviKe9fxV/7OqNR4vvZ83ttbb+CxJ7
|
16
|
+
3mwoQHufjrGcxsWUKrmtJsXAGZpGJFw7ygnKDAfDPKWSKYeUuQ417AutPWSvhWqa
|
17
|
+
LEohhNCeHJj/+3U2vj2g2rvy0AASeMff9IMz/lpPZ2bjJQjlITXXPvswB2/uZSRT
|
18
|
+
KWEifqfo03/nTjhzN7dz2hXEeZHroCq6FZa1R6smYVM79TORFWiKfdKtjXI8wQQ2
|
19
|
+
BhVJpWQB2yw9d/4Q7x2EPjJEPiVoRLW0vF8uxr++14nhVkSpYJCSNAw=
|
16
20
|
-----END CERTIFICATE-----
|
@@ -1,15 +1,27 @@
|
|
1
1
|
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
2
|
+
MIIEpAIBAAKCAQEA21N74n1PaJk8eU+hArmJ768q+IljzwOLF4XbjvGg9yHQPMx5
|
3
|
+
T7WZ5odJYhN9JwGNNMSmuBIrMbPf1IFKB5RG+ZwrWLOjnfaY4rsq8thuZQRyIS5V
|
4
|
+
TU20XkSn44a93sFMXJ0DdMYsp437FDG86FSNWbBg1mfYBeAx4NwHHHnt/vwTQQ01
|
5
|
+
osWF4euA/WCNU4/93wtSNrWlKd9o3S1xPZmwgckJZORGXwWVFsfOvBbcMM1N8pm6
|
6
|
+
trkELU5eWtEB6i1MG9J5HXsKEb2mSRZKKSPtbYMtB7PqWEDPfb0Fku1YjOam1WLT
|
7
|
+
4pf+FVViW8f5EIv06OP0PE8WGyEZKHiUjqvVNwIDAQABAoIBAQCbixNaxt/gIHyg
|
8
|
+
0/YuRoMqdqIU7OrZz3t/TTEuqPItEc/qrmCCRRpGQT+rzIJ/fTw1ZhmOhWQYtaZR
|
9
|
+
wPdNdLz5HOYo3A13Y4F9mpuU6iUwgvylx4Q7dJYsHKisVcymA5QyQjBHSpw0oB6m
|
10
|
+
bbe5VO2B4/JpW+/6CsuU2rY4XciJgc+MDitqxgZOfMK8xcOiQ4EDa1OxL3TeZcYQ
|
11
|
+
F5yUc39DhIDV03O/AFYnMZUMUQFNpSAyktms6YUL1JhwozcCaXB/da8TVRrLz1pl
|
12
|
+
Cj3p2VgzHKa40NVCjXc2nvPCYRMF0yD0Jm9fRJPsCkVS3wtGgqQW+rwum1p/UPTr
|
13
|
+
6x0MGd7RAoGBAPbxwBLiPyRnLy+9qgu2fS0JwXcG/6d6bhUrWS4hjzoggKyDz8Jg
|
14
|
+
4KByXxnJVigZ8qlkynZKfb3FMuAPNxHxFhK5qPDNxV2UsdnR6RbDc9Sba8mBmzhl
|
15
|
+
vvJSH7Nf7B0ws7sTzecXkh3BkaP5rhPycOxdLJs705p4RUALkDW7hn1NAoGBAONe
|
16
|
+
dfmO49s2y1Ye2XrRCmGqfVa0n4pFmQajgputc4BPkf3XudtH365O0QEwt54Nw3dQ
|
17
|
+
IvFzq/f0XVhkw4Coo38WZ4nTctbW/ZkVvKJnk2DJE1ubNJvw1wHzwz848BVT/b4Z
|
18
|
+
VplqNDPvWmEmGFzrLeOwPZfDcglDxaCpjF7q0GqTAoGAcEOjUHJuxjvqpceR4NVL
|
19
|
+
vwfqXhRecWMlXJZiaqhzFrfkB4m9D98+/3I/bdesRXrWaNAbgv+GfpmB8X65SHzT
|
20
|
+
zht9hEvn6A1LdX0KfIDKzeMCc49qY49N6ZgQNVnsW7DiZLAyMVbz5Hc1oNhHnWXg
|
21
|
+
lHQfbUsbfeQjh2Q6YVMpZxkCgYAmC2pGJciup46CjIrraAsKqJJsbbC8XETsvXNf
|
22
|
+
RTisYaQWC4DH1lDxQ7LpNhOjWL46Oqh+KlK+HJ956PJlltI0s7UDdOQkWrj4YpC7
|
23
|
+
xAT/DuY0T9YPuc7gPr+O1qIlj3ZH1smMxh6SChzfYJZ3BcsZ7CWCPWvZbQOmjHg2
|
24
|
+
cagKDQKBgQCjuICU3aElEXyGwPCEazVakgcuAuiAAjECQrHrbSVPaTDu6Cumupkw
|
25
|
+
50ypk/qJ3DegEumpufwLg37A9yFogkkHBI9Sw0PVjzXM0iWJsHceLTHWUgJBWcl3
|
26
|
+
5Sl/AacXbUHz4NMqARNVrfR3DP33Z/YXJ4bpsVswEjD51jPwwluwyA==
|
15
27
|
-----END RSA PRIVATE KEY-----
|
@@ -250,6 +250,13 @@ unless RUBY_PLATFORM =~ /java/
|
|
250
250
|
request
|
251
251
|
end
|
252
252
|
|
253
|
+
it 'sets ssl_cipher_list' do
|
254
|
+
request.auth.ssl.ciphers = ["AES128"]
|
255
|
+
curb.expects(:set).with(any_parameters).at_least(1)
|
256
|
+
curb.expects(:set).with(:ssl_cipher_list, anything)
|
257
|
+
adapter.request(:get)
|
258
|
+
end
|
259
|
+
|
253
260
|
context 'sets ssl_version' do
|
254
261
|
it 'defaults to nil when no ssl_version is specified' do
|
255
262
|
curb.expects(:ssl_version=).with(nil)
|
@@ -278,6 +285,16 @@ unless RUBY_PLATFORM =~ /java/
|
|
278
285
|
adapter.request(:get)
|
279
286
|
end
|
280
287
|
end
|
288
|
+
it 'raises error when min_version not nil' do
|
289
|
+
request.auth.ssl.min_version = :TLS1_2
|
290
|
+
expect{ adapter.request(:get) }.
|
291
|
+
to raise_error(HTTPI::NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.')
|
292
|
+
end
|
293
|
+
it 'raises error when max_version not nil' do
|
294
|
+
request.auth.ssl.max_version = :TLS1_2
|
295
|
+
expect{ adapter.request(:get) }.
|
296
|
+
to raise_error(HTTPI::NotSupportedError, 'Curb adapter does not support #min_version or #max_version. Please, use #ssl_version instead.')
|
297
|
+
end
|
281
298
|
end
|
282
299
|
|
283
300
|
context "(for SSL client auth)" do
|
@@ -2,7 +2,7 @@ require "spec_helper"
|
|
2
2
|
require "httpi/adapter/em_http"
|
3
3
|
require "httpi/request"
|
4
4
|
|
5
|
-
|
5
|
+
unless RUBY_PLATFORM =~ /java/
|
6
6
|
HTTPI::Adapter.load_adapter(:em_http)
|
7
7
|
|
8
8
|
describe HTTPI::Adapter::EmHttpRequest do
|
@@ -150,7 +150,7 @@ begin
|
|
150
150
|
|
151
151
|
it "raises an error for HTTP digest auth" do
|
152
152
|
request.auth.digest "username", "password"
|
153
|
-
expect { adapter.request(:get) }.to raise_error
|
153
|
+
expect { adapter.request(:get) }.to raise_error HTTPI::NotSupportedError
|
154
154
|
end
|
155
155
|
end
|
156
156
|
|
@@ -177,10 +177,4 @@ begin
|
|
177
177
|
end
|
178
178
|
|
179
179
|
end
|
180
|
-
rescue LoadError => e
|
181
|
-
if e.message =~ /fiber/
|
182
|
-
warn "LoadError: #{e.message} (EventMachine requires fibers)"
|
183
|
-
else
|
184
|
-
raise e
|
185
|
-
end
|
186
180
|
end
|
@@ -141,6 +141,13 @@ describe HTTPI::Adapter::HTTPClient do
|
|
141
141
|
|
142
142
|
adapter.request(:get)
|
143
143
|
end
|
144
|
+
|
145
|
+
it 'should set the ciphers if specified' do
|
146
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
147
|
+
ssl_config.expects(:ciphers=).with(request.auth.ssl.ciphers)
|
148
|
+
|
149
|
+
adapter.request(:get)
|
150
|
+
end
|
144
151
|
end
|
145
152
|
|
146
153
|
context "(for SSL client auth)" do
|
@@ -178,6 +185,17 @@ describe HTTPI::Adapter::HTTPClient do
|
|
178
185
|
|
179
186
|
adapter.request(:get)
|
180
187
|
end
|
188
|
+
|
189
|
+
it 'raises error when min_version not nil' do
|
190
|
+
request.auth.ssl.min_version = :TLS1_2
|
191
|
+
expect{ adapter.request(:get) }.
|
192
|
+
to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
|
193
|
+
end
|
194
|
+
it 'raises error when max_version not nil' do
|
195
|
+
request.auth.ssl.max_version = :TLS1_2
|
196
|
+
expect{ adapter.request(:get) }.
|
197
|
+
to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
|
198
|
+
end
|
181
199
|
end
|
182
200
|
|
183
201
|
context "(for SSL client auth with a verify mode of :none with no certs provided)" do
|
data/spec/httpi/auth/ssl_spec.rb
CHANGED
@@ -4,6 +4,7 @@ require "httpi/auth/ssl"
|
|
4
4
|
describe HTTPI::Auth::SSL do
|
5
5
|
before(:all) do
|
6
6
|
@ssl_versions = HTTPI::Auth::SSL::SSL_VERSIONS
|
7
|
+
@min_max_versions = HTTPI::Auth::SSL::MIN_MAX_VERSIONS
|
7
8
|
end
|
8
9
|
|
9
10
|
describe "VERIFY_MODES" do
|
@@ -158,6 +159,53 @@ describe HTTPI::Auth::SSL do
|
|
158
159
|
end
|
159
160
|
end
|
160
161
|
|
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
|
+
|
192
|
+
describe '#ciphers' do
|
193
|
+
subject { ssl.ciphers }
|
194
|
+
let(:ssl) { HTTPI::Auth::SSL.new }
|
195
|
+
|
196
|
+
context 'without ciphers' do
|
197
|
+
before { ssl.ciphers = nil }
|
198
|
+
|
199
|
+
it { is_expected.to eq(nil) }
|
200
|
+
end
|
201
|
+
|
202
|
+
context 'with ciphers' do
|
203
|
+
before { ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers }
|
204
|
+
|
205
|
+
it { is_expected.to be_any.and(all(be_an_instance_of(String))) }
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
161
209
|
def ssl
|
162
210
|
ssl = HTTPI::Auth::SSL.new
|
163
211
|
ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
data/spec/httpi/httpi_spec.rb
CHANGED
@@ -6,11 +6,9 @@ require "excon"
|
|
6
6
|
require "net/http/persistent"
|
7
7
|
require "http"
|
8
8
|
|
9
|
-
unless
|
9
|
+
unless RUBY_PLATFORM =~ /java/
|
10
10
|
require "em-synchrony"
|
11
11
|
require "em-http-request"
|
12
|
-
end
|
13
|
-
unless RUBY_PLATFORM =~ /java/
|
14
12
|
require "curb"
|
15
13
|
end
|
16
14
|
|
@@ -294,7 +292,7 @@ describe HTTPI do
|
|
294
292
|
end
|
295
293
|
|
296
294
|
HTTPI::Adapter::ADAPTERS.each do |adapter, opts|
|
297
|
-
unless (adapter == :em_http
|
295
|
+
unless (adapter == :em_http || adapter == :curb) && RUBY_PLATFORM =~ /java/
|
298
296
|
client_class = {
|
299
297
|
:httpclient => lambda { HTTPClient },
|
300
298
|
:curb => lambda { Curl::Easy },
|
@@ -123,6 +123,15 @@ describe HTTPI::Adapter::Curb do
|
|
123
123
|
response = HTTPI.get(request, adapter)
|
124
124
|
expect(response.body).to eq("get")
|
125
125
|
end
|
126
|
+
|
127
|
+
it "works with ciphers" do
|
128
|
+
request = HTTPI::Request.new(@server.url)
|
129
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
130
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
131
|
+
|
132
|
+
response = HTTPI.get(request, adapter)
|
133
|
+
expect(response.body).to eq("get")
|
134
|
+
end
|
126
135
|
end
|
127
136
|
|
128
137
|
end
|
@@ -3,8 +3,8 @@ require "integration/support/server"
|
|
3
3
|
|
4
4
|
describe HTTPI::Adapter::EmHttpRequest do
|
5
5
|
|
6
|
-
# em_http is not supported on
|
7
|
-
unless
|
6
|
+
# em_http is not supported on java
|
7
|
+
unless RUBY_PLATFORM =~ /java/
|
8
8
|
require "em-synchrony"
|
9
9
|
|
10
10
|
subject(:adapter) { :em_http }
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "integration/support/server"
|
3
3
|
|
4
|
-
describe HTTPI::Adapter::
|
4
|
+
describe HTTPI::Adapter::Excon do
|
5
5
|
|
6
6
|
subject(:adapter) { :excon }
|
7
7
|
|
@@ -129,6 +129,16 @@ describe HTTPI::Adapter::HTTPClient do
|
|
129
129
|
expect(response.body).to eq("get")
|
130
130
|
end
|
131
131
|
|
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
|
+
|
132
142
|
it "works with client cert and key provided as file path" do
|
133
143
|
request = HTTPI::Request.new(@server.url)
|
134
144
|
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
@@ -149,6 +159,15 @@ describe HTTPI::Adapter::HTTPClient do
|
|
149
159
|
response = HTTPI.get(request, adapter)
|
150
160
|
expect(response.body).to eq("get")
|
151
161
|
end
|
162
|
+
|
163
|
+
it "works with ciphers" do
|
164
|
+
request = HTTPI::Request.new(@server.url)
|
165
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
166
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
167
|
+
|
168
|
+
response = HTTPI.get(request, adapter)
|
169
|
+
expect(response.body).to eq("get")
|
170
|
+
end
|
152
171
|
end
|
153
172
|
end
|
154
173
|
|
@@ -1,44 +1,19 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
MJJFRkSu6d/Ph5ypzBVw2YMT/nsOo5VwMUGLgS7YVjU+u/HNWz80J3oO17mNZllj
|
20
|
-
PvORJcnjwlroDnS58KoJ7GDgejv3ESWADvX1OHLE4cRkiQGeLoEU4pxdCxXRqX0U
|
21
|
-
PbwIkZN9mXVcrmPHq8MWi4eC/V7hnbZETMHuWhUoiNdOEfsAXr3iP4KjyyRdwc7a
|
22
|
-
d/xgcK06UVQRL/HbEYGiQL056mc=
|
23
|
-
-----END CERTIFICATE-----
|
24
|
-
-----BEGIN CERTIFICATE-----
|
25
|
-
MIIDaDCCAlCgAwIBAgIBATANBgkqhkiG9w0BAQUFADA8MQswCQYDVQQGDAJKUDES
|
26
|
-
MBAGA1UECgwJSklOLkdSLkpQMQwwCgYDVQQLDANSUlIxCzAJBgNVBAMMAkNBMB4X
|
27
|
-
DTA0MDEzMDAwNDMyN1oXDTM1MDEyMjAwNDMyN1owPzELMAkGA1UEBgwCSlAxEjAQ
|
28
|
-
BgNVBAoMCUpJTi5HUi5KUDEMMAoGA1UECwwDUlJSMQ4wDAYDVQQDDAVTdWJDQTCC
|
29
|
-
ASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJ0Ou7AyRcRXnB/kVHv/6kwe
|
30
|
-
ANzgg/DyJfsAUqW90m7Lu1nqyug8gK0RBd77yU0w5HOAMHTVSdpjZK0g2sgx4Mb1
|
31
|
-
d/213eL9TTl5MRVEChTvQr8q5DVG/8fxPPE7fMI8eOAzd98/NOAChk+80r4Sx7fC
|
32
|
-
kGVEE1bKwY1MrUsUNjOY2d6t3M4HHV3HX1V8ShuKfsHxgCmLzdI8U+5CnQedFgkm
|
33
|
-
3e+8tr8IX5RR1wA1Ifw9VadF7OdI/bGMzog/Q8XCLf+WPFjnK7Gcx6JFtzF6Gi4x
|
34
|
-
4dp1Xl45JYiVvi9zQ132wu8A1pDHhiNgQviyzbP+UjcB/tsOpzBQF8abYzgEkWEC
|
35
|
-
AwEAAaNyMHAwDwYDVR0TAQH/BAUwAwEB/zAxBglghkgBhvhCAQ0EJBYiUnVieS9P
|
36
|
-
cGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQUlCjXWLsReYzH
|
37
|
-
LzsxwVnCXmKoB/owCwYDVR0PBAQDAgEGMA0GCSqGSIb3DQEBBQUAA4IBAQCJ/OyN
|
38
|
-
rT8Cq2Y+G2yA/L1EMRvvxwFBqxavqaqHl/6rwsIBFlB3zbqGA/0oec6MAVnYynq4
|
39
|
-
c4AcHTjx3bQ/S4r2sNTZq0DH4SYbQzIobx/YW8PjQUJt8KQdKMcwwi7arHP7A/Ha
|
40
|
-
LKu8eIC2nsUBnP4NhkYSGhbmpJK+PFD0FVtD0ZIRlY/wsnaZNjWWcnWF1/FNuQ4H
|
41
|
-
ySjIblqVQkPuzebv3Ror6ZnVDukn96Mg7kP4u6zgxOeqlJGRe1M949SS9Vudjl8X
|
42
|
-
SF4aZUUB9pQGhsqQJVqaz2OlhGOp9D0q54xko/rekjAIcuDjl1mdX4F2WRrzpUmZ
|
43
|
-
uY/bPeOBYiVsOYVe
|
2
|
+
MIIDDjCCAfagAwIBAgIBAzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
|
3
|
+
GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
|
4
|
+
ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA4MRMwEQYKCZImiZPyLGQBGRYDbmV0
|
5
|
+
MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwggEiMA0GCSqGSIb3
|
6
|
+
DQEBAQUAA4IBDwAwggEKAoIBAQDIHxrFcS2JkRQbXLFosb32unVkVuwHSPSt6Dpl
|
7
|
+
2jUQHP/bceAx/d9waHYf8rlbCFAIoduZDOc7XCJUidgcG5NfLJyQpkkWOU8CGWH+
|
8
|
+
Ipl4AE8auYCcy/0T7BQqaRC41HPmrJG1CC40rqcY47lUO2haI+vj5TZFHNhAbRat
|
9
|
+
rR1iD1veis2gBZtrMzd4IlpvEHGv6ghfnSc20za4exmapjp/uAAIOXpeFX8QHumA
|
10
|
+
bty4dd+iHpKjDzUrhG9Qa5v28ii2K1AcbczUQ7FzSp2/GoRSjF+WY6i86N9Z1M97
|
11
|
+
2PEgy0IG5l6JHu1P0/rd00hN0h0Owzv3V5ldMLZap7+pVFQTAgMBAAGjIzAhMA8G
|
12
|
+
A1UdEwEB/wQFMAMBAf8wDgYDVR0PAQH/BAQDAgEGMA0GCSqGSIb3DQEBCwUAA4IB
|
13
|
+
AQA3GWpy4bYLOHLENDTUBeclF6cDdYiautD6gxd1SDLMWOhAUF7ywwT87OAJdr1I
|
14
|
+
+W1TUv5BRG21rNm1QsZfLbStdKA1mpiET/9nYN7m1YauL5hI3yD49TGuO9/sxcE5
|
15
|
+
zNW7D3VBVNq+pyT21/TvLAgxCNvjjm7byzyIOcoRUyZx8WhCf8nUT6cEShXqEg4Q
|
16
|
+
iUBSLI38tiQoZneuVzDRlXBY0PqoB19l2Kg9yThHjPTVhw5EAQSDKXCCvaxAbVw6
|
17
|
+
ZPLNnOdK6DvqEZ3GC5WlaHQdmLxmN4OfV6AEtpgqgGY9u8K1ylTr3ET7xLK7bhcA
|
18
|
+
oZsggEVZr1Ifx9BWIazRNwlw
|
44
19
|
-----END CERTIFICATE-----
|
@@ -1,19 +1,19 @@
|
|
1
1
|
-----BEGIN CERTIFICATE-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
2
|
+
MIIDBDCCAeygAwIBAgIBBzANBgkqhkiG9w0BAQsFADA4MRMwEQYKCZImiZPyLGQB
|
3
|
+
GRYDbmV0MRQwEgYKCZImiZPyLGQBGRYEcHVtYTELMAkGA1UEAwwCQ0EwHhcNMjAw
|
4
|
+
ODAxMDAwMDAwWhcNMjQwODAxMDAwMDAwWjA/MRMwEQYKCZImiZPyLGQBGRYDbmV0
|
5
|
+
MRQwEgYKCZImiZPyLGQBGRYEcHVtYTESMBAGA1UEAwwJbG9jYWxob3N0MIIBIjAN
|
6
|
+
BgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvXOg3gTrGJfVft9cSrfGRnEZezDB
|
7
|
+
L93fcLwJAoaXGxbEg1RW/fOrSpSNemuqOvbzczV7m5eYTf1lHPBJsndbYyijIR1+
|
8
|
+
Fp4tjFDp76SC3hxCIc3uYXIz0qQwSOAi1z15zobS4xF29jlsXWtfBl9fivjzdj/f
|
9
|
+
pbZ+JPYOrlcJAf6Xmr3xh//13rOI0ytBMlWf51z/iAZBLm2wvbt+nR7B6koAdTgM
|
10
|
+
Coe+gOtcLWYY5ApJ4qB9knGdxWoF5p7guHHw2aGTM0jyhgBowfVkFRiE2JUmODae
|
11
|
+
g+dHsd8ogWbqhGyZTredJF/NRrLKU0h+t7ldKHvXEZy4qyqQlvKoTpODqQIDAQAB
|
12
|
+
oxIwEDAOBgNVHQ8BAf8EBAMCBLAwDQYJKoZIhvcNAQELBQADggEBAI/bcQP4Hu9O
|
13
|
+
OtaaIjVxN8+9jXUOrMpSogmZ4bRKImispt9SA+sbxec7iOMM2pG3Py2yi0hWGzii
|
14
|
+
hSebWIsM1JuPj7ks9l8nGRxpGeInJwTkJorG4ZLEypoS2wW3fQZGx3o4da5V+U2Z
|
15
|
+
HEY0wQTbPBqqnyeZ16ZFNVCzw8y9l7y7CEFjvUO3sq0pne9r7Z+XVgjGyBdBYkJS
|
16
|
+
0kcqPBXFCMHrWH5UlacYlM5cqgoVztOp2STGmR3XR7a34oueeA10QSP+jzeYvWA1
|
17
|
+
wTYA762uU2ReCdujfNbf8V1tZWAH36KldM3hhDNWeveAGxxj1h2R9T/k2kHl/a7D
|
18
|
+
I3VdS59vjJY=
|
19
19
|
-----END CERTIFICATE-----
|
@@ -1,15 +1,27 @@
|
|
1
1
|
-----BEGIN RSA PRIVATE KEY-----
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
2
|
+
MIIEpQIBAAKCAQEAvXOg3gTrGJfVft9cSrfGRnEZezDBL93fcLwJAoaXGxbEg1RW
|
3
|
+
/fOrSpSNemuqOvbzczV7m5eYTf1lHPBJsndbYyijIR1+Fp4tjFDp76SC3hxCIc3u
|
4
|
+
YXIz0qQwSOAi1z15zobS4xF29jlsXWtfBl9fivjzdj/fpbZ+JPYOrlcJAf6Xmr3x
|
5
|
+
h//13rOI0ytBMlWf51z/iAZBLm2wvbt+nR7B6koAdTgMCoe+gOtcLWYY5ApJ4qB9
|
6
|
+
knGdxWoF5p7guHHw2aGTM0jyhgBowfVkFRiE2JUmODaeg+dHsd8ogWbqhGyZTred
|
7
|
+
JF/NRrLKU0h+t7ldKHvXEZy4qyqQlvKoTpODqQIDAQABAoIBAQCCtt8NkNMs2sYB
|
8
|
+
jdc97mKtg6eTKeaBQlLCk9qblYV4uVLJUk3bVl6fTLP4/YQsvurmWMZ6ajQ5y1YS
|
9
|
+
i3At5NB3MDitxo2SyXyfzcw6/oUU/uZaMJ4DOiqrcYGnJo6jd9UtPDURWqF77c7o
|
10
|
+
/gZIfVGMr4w70IJc8fdDRUqH26Fpb7Gp0+RNUXtM9tSovkX/yICje7Hp4IIiJJ0t
|
11
|
+
KGepdHfddshR4OIALh0k3jC9zfbYfSdIKZuGBf7bmjJTByLavjcG6HFLyt7aZBt3
|
12
|
+
136hXAOvMO780WW2vQ8xAYkd+8bf4db4fjUpw3NWJ5wVdQhI9jhkAc9LhhxiDVoI
|
13
|
+
g9IyaSUBAoGBAObajQ24JlNg11ZZffPZwmvMlMDyZ8pZ5dk/Up9nOvCp1J2+7ef/
|
14
|
+
6wjkOhrSyIPpvJCmftOn0c9IkV7tk5673Kjmly33QiIwiEeEG3lNN6GytiXIGqFV
|
15
|
+
ScPGznO/rNeKUsMFu3SXZNYs7aYqr9OCadwATuh+IzTQAx3T3prno4F5AoGBANIW
|
16
|
+
kJRF2Pl4yWc7MRjF+WnGfhJHv7VOcLlmFD1fa/IIM9xuBRgikiBWHtFwLoXknsY8
|
17
|
+
y2VqNrPEkjCp+qLpXLC8l3dzpNU33Z42h/tUfoTmgSgDUQXGggjzbcS8cf+1D55z
|
18
|
+
KuPazKAndyiuhIENk1gE+5RKdNyjYP2sI4+L5jexAoGBANxx2rw9GywHj9n/P006
|
19
|
+
pnO2Ol49nGsYiWp5E3bwZtIl+shf6GLgeRpWhj3TBnMhIlWnB/kpiiq8i0Tw7URo
|
20
|
+
9H+9IqRcNqTbX2ebeXjOCc+5DkLp4LQq83OmRsM1R+HTTtC4ipb9cucqpA1HOftp
|
21
|
+
z5isGq3ctdXaxP8YsLuPcw1RAoGAXZx0W70ryy2JAJidbd55Hiq17ktOHumOzO2x
|
22
|
+
Qw+Lt9Lz2NqlJnXxCruVC9miwUJ3hPl93/iN21hRk6GJ7qFxDcda7nz3C5LTCzZd
|
23
|
+
LR4fKfTTxBKGPb6QHpDpbmpRmZECHqZOjCzoVMyBCf2JST/VUbkWqKLso4uhIidb
|
24
|
+
yRCbSmECgYEAp+IuwpnMxVPxP52/xPFVcAxH2pDfmn5TJLJCNuKEUAS9ncZuz7rh
|
25
|
+
jJxtbC4AoGsS0+TdxnlMBvBpZE3QddQmjvey77yu/OvRUX2m/J/d+I2duTaHGR9Z
|
26
|
+
9VMxtlFY+DbDkJI2HVVxu5XfLKMJSEsMza8K64Ntx3XY3dJLCHrR1EY=
|
15
27
|
-----END RSA PRIVATE KEY-----
|
@@ -131,6 +131,25 @@ describe HTTPI::Adapter::HTTP do
|
|
131
131
|
response = HTTPI.get(request, adapter)
|
132
132
|
expect(response.body).to eq("get")
|
133
133
|
end
|
134
|
+
|
135
|
+
it "works with min_version/max_version" do
|
136
|
+
request = HTTPI::Request.new(@server.url)
|
137
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
138
|
+
request.auth.ssl.min_version = :TLS1_2
|
139
|
+
request.auth.ssl.max_version = :TLS1_2
|
140
|
+
|
141
|
+
response = HTTPI.get(request, adapter)
|
142
|
+
expect(response.body).to eq("get")
|
143
|
+
end
|
144
|
+
|
145
|
+
it "works with ciphers" do
|
146
|
+
request = HTTPI::Request.new(@server.url)
|
147
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
148
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
149
|
+
|
150
|
+
response = HTTPI.get(request, adapter)
|
151
|
+
expect(response.body).to eq("get")
|
152
|
+
end
|
134
153
|
end
|
135
154
|
end
|
136
155
|
|
@@ -121,6 +121,15 @@ describe HTTPI::Adapter::HTTPClient do
|
|
121
121
|
response = HTTPI.get(request, adapter)
|
122
122
|
expect(response.body).to eq("get")
|
123
123
|
end
|
124
|
+
|
125
|
+
it "works with ciphers" do
|
126
|
+
request = HTTPI::Request.new(@server.url)
|
127
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
128
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
129
|
+
|
130
|
+
response = HTTPI.get(request, adapter)
|
131
|
+
expect(response.body).to eq("get")
|
132
|
+
end
|
124
133
|
end
|
125
134
|
end
|
126
135
|
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
require "integration/support/server"
|
3
|
+
require "net/http/persistent"
|
3
4
|
|
4
|
-
describe HTTPI::Adapter::
|
5
|
+
describe HTTPI::Adapter::NetHTTPPersistent do
|
5
6
|
|
6
7
|
subject(:adapter) { :net_http_persistent }
|
7
8
|
|
@@ -38,7 +39,7 @@ describe HTTPI::Adapter::NetHTTP do
|
|
38
39
|
|
39
40
|
expect do
|
40
41
|
HTTPI.get(request, adapter)
|
41
|
-
end.to raise_exception(Net::
|
42
|
+
end.to raise_exception(Net::ReadTimeout)
|
42
43
|
end
|
43
44
|
|
44
45
|
it "executes GET requests" do
|
@@ -110,6 +111,7 @@ describe HTTPI::Adapter::NetHTTP do
|
|
110
111
|
before :all do
|
111
112
|
@server = IntegrationServer.run(:ssl => true)
|
112
113
|
end
|
114
|
+
|
113
115
|
after :all do
|
114
116
|
@server.stop
|
115
117
|
end
|
@@ -122,6 +124,15 @@ describe HTTPI::Adapter::NetHTTP do
|
|
122
124
|
response = HTTPI.get(request, adapter)
|
123
125
|
expect(response.body).to eq("get")
|
124
126
|
end
|
127
|
+
|
128
|
+
it "works with ciphers" do
|
129
|
+
request = HTTPI::Request.new(@server.url)
|
130
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
131
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
132
|
+
|
133
|
+
response = HTTPI.get(request, adapter)
|
134
|
+
expect(response.body).to eq("get")
|
135
|
+
end
|
125
136
|
end
|
126
137
|
end
|
127
138
|
|
@@ -93,11 +93,19 @@ describe HTTPI::Adapter::NetHTTP do
|
|
93
93
|
end
|
94
94
|
}
|
95
95
|
let(:request_body) { nil }
|
96
|
-
|
96
|
+
|
97
|
+
subject(:response) { HTTPI.request(http_method, request, adapter) }
|
97
98
|
|
98
99
|
shared_examples_for "any supported custom method" do
|
99
|
-
|
100
|
-
|
100
|
+
describe '#body' do
|
101
|
+
subject(:body) {response.body}
|
102
|
+
it { is_expected.to be == http_method.to_s }
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '#headers' do
|
106
|
+
subject(:headers) {response.headers}
|
107
|
+
it { is_expected.to include('content-type' => "text/plain")}
|
108
|
+
end
|
101
109
|
end
|
102
110
|
|
103
111
|
context "PATCH method" do
|
@@ -217,6 +225,25 @@ describe HTTPI::Adapter::NetHTTP do
|
|
217
225
|
response = HTTPI.get(request, adapter)
|
218
226
|
expect(response.body).to eq("get")
|
219
227
|
end
|
228
|
+
|
229
|
+
it "works with min_version/max_version" do
|
230
|
+
request = HTTPI::Request.new(@server.url)
|
231
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
232
|
+
request.auth.ssl.min_version = :TLS1_2
|
233
|
+
request.auth.ssl.max_version = :TLS1_2
|
234
|
+
|
235
|
+
response = HTTPI.get(request, adapter)
|
236
|
+
expect(response.body).to eq("get")
|
237
|
+
end
|
238
|
+
|
239
|
+
it "works with ciphers" do
|
240
|
+
request = HTTPI::Request.new(@server.url)
|
241
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
242
|
+
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
243
|
+
|
244
|
+
response = HTTPI.get(request, adapter)
|
245
|
+
expect(response.body).to eq("get")
|
246
|
+
end
|
220
247
|
end
|
221
248
|
end
|
222
249
|
|
@@ -4,7 +4,6 @@ require "puma/minissl"
|
|
4
4
|
require "integration/support/application"
|
5
5
|
|
6
6
|
class IntegrationServer
|
7
|
-
|
8
7
|
def self.run(options = {})
|
9
8
|
server = new(options)
|
10
9
|
server.run
|
@@ -76,7 +75,7 @@ class IntegrationServer
|
|
76
75
|
|
77
76
|
context.key = IntegrationServer.ssl_key_file
|
78
77
|
context.cert = IntegrationServer.ssl_cert_file
|
79
|
-
context.verify_mode = Puma::MiniSSL::
|
78
|
+
context.verify_mode = Puma::MiniSSL::VERIFY_NONE
|
80
79
|
|
81
80
|
context
|
82
81
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpi
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Harrington
|
8
8
|
- Martin Tepper
|
9
|
-
autorequire:
|
9
|
+
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2021-12-17 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rack
|
@@ -25,20 +25,6 @@ dependencies:
|
|
25
25
|
- - ">="
|
26
26
|
- !ruby/object:Gem::Version
|
27
27
|
version: '0'
|
28
|
-
- !ruby/object:Gem::Dependency
|
29
|
-
name: socksify
|
30
|
-
requirement: !ruby/object:Gem::Requirement
|
31
|
-
requirements:
|
32
|
-
- - ">="
|
33
|
-
- !ruby/object:Gem::Version
|
34
|
-
version: '0'
|
35
|
-
type: :runtime
|
36
|
-
prerelease: false
|
37
|
-
version_requirements: !ruby/object:Gem::Requirement
|
38
|
-
requirements:
|
39
|
-
- - ">="
|
40
|
-
- !ruby/object:Gem::Version
|
41
|
-
version: '0'
|
42
28
|
- !ruby/object:Gem::Dependency
|
43
29
|
name: rubyntlm
|
44
30
|
requirement: !ruby/object:Gem::Requirement
|
@@ -59,28 +45,28 @@ dependencies:
|
|
59
45
|
requirements:
|
60
46
|
- - "~>"
|
61
47
|
- !ruby/object:Gem::Version
|
62
|
-
version: '
|
48
|
+
version: '13.0'
|
63
49
|
type: :development
|
64
50
|
prerelease: false
|
65
51
|
version_requirements: !ruby/object:Gem::Requirement
|
66
52
|
requirements:
|
67
53
|
- - "~>"
|
68
54
|
- !ruby/object:Gem::Version
|
69
|
-
version: '
|
55
|
+
version: '13.0'
|
70
56
|
- !ruby/object:Gem::Dependency
|
71
57
|
name: rspec
|
72
58
|
requirement: !ruby/object:Gem::Requirement
|
73
59
|
requirements:
|
74
60
|
- - "~>"
|
75
61
|
- !ruby/object:Gem::Version
|
76
|
-
version: '
|
62
|
+
version: '3.5'
|
77
63
|
type: :development
|
78
64
|
prerelease: false
|
79
65
|
version_requirements: !ruby/object:Gem::Requirement
|
80
66
|
requirements:
|
81
67
|
- - "~>"
|
82
68
|
- !ruby/object:Gem::Version
|
83
|
-
version: '
|
69
|
+
version: '3.5'
|
84
70
|
- !ruby/object:Gem::Dependency
|
85
71
|
name: mocha
|
86
72
|
requirement: !ruby/object:Gem::Requirement
|
@@ -101,14 +87,14 @@ dependencies:
|
|
101
87
|
requirements:
|
102
88
|
- - "~>"
|
103
89
|
- !ruby/object:Gem::Version
|
104
|
-
version:
|
90
|
+
version: '5.0'
|
105
91
|
type: :development
|
106
92
|
prerelease: false
|
107
93
|
version_requirements: !ruby/object:Gem::Requirement
|
108
94
|
requirements:
|
109
95
|
- - "~>"
|
110
96
|
- !ruby/object:Gem::Version
|
111
|
-
version:
|
97
|
+
version: '5.0'
|
112
98
|
- !ruby/object:Gem::Dependency
|
113
99
|
name: webmock
|
114
100
|
requirement: !ruby/object:Gem::Requirement
|
@@ -129,14 +115,15 @@ executables: []
|
|
129
115
|
extensions: []
|
130
116
|
extra_rdoc_files: []
|
131
117
|
files:
|
118
|
+
- ".github/workflows/development.yml"
|
132
119
|
- ".gitignore"
|
133
120
|
- ".rspec"
|
134
|
-
- ".travis.yml"
|
135
121
|
- CHANGELOG.md
|
136
122
|
- Gemfile
|
137
123
|
- LICENSE
|
138
124
|
- README.md
|
139
125
|
- Rakefile
|
126
|
+
- UPDATING.md
|
140
127
|
- httpi.gemspec
|
141
128
|
- lib/httpi.rb
|
142
129
|
- lib/httpi/adapter.rb
|
@@ -204,7 +191,7 @@ homepage: http://github.com/savonrb/httpi
|
|
204
191
|
licenses:
|
205
192
|
- MIT
|
206
193
|
metadata: {}
|
207
|
-
post_install_message:
|
194
|
+
post_install_message:
|
208
195
|
rdoc_options: []
|
209
196
|
require_paths:
|
210
197
|
- lib
|
@@ -212,16 +199,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
212
199
|
requirements:
|
213
200
|
- - ">="
|
214
201
|
- !ruby/object:Gem::Version
|
215
|
-
version:
|
202
|
+
version: '2.3'
|
216
203
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
217
204
|
requirements:
|
218
205
|
- - ">="
|
219
206
|
- !ruby/object:Gem::Version
|
220
207
|
version: '0'
|
221
208
|
requirements: []
|
222
|
-
|
223
|
-
|
224
|
-
signing_key:
|
209
|
+
rubygems_version: 3.2.7
|
210
|
+
signing_key:
|
225
211
|
specification_version: 4
|
226
212
|
summary: Common interface for Ruby's HTTP libraries
|
227
213
|
test_files: []
|
data/.travis.yml
DELETED