httpi 2.4.3 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (43) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/development.yml +48 -0
  3. data/CHANGELOG.md +23 -0
  4. data/Gemfile +8 -6
  5. data/README.md +20 -16
  6. data/UPDATING.md +7 -0
  7. data/httpi.gemspec +5 -8
  8. data/lib/httpi/adapter/curb.rb +7 -2
  9. data/lib/httpi/adapter/em_http.rb +5 -4
  10. data/lib/httpi/adapter/excon.rb +6 -1
  11. data/lib/httpi/adapter/http.rb +9 -0
  12. data/lib/httpi/adapter/httpclient.rb +5 -0
  13. data/lib/httpi/adapter/net_http.rb +10 -2
  14. data/lib/httpi/adapter/net_http_persistent.rb +6 -2
  15. data/lib/httpi/auth/ssl.rb +53 -2
  16. data/lib/httpi/request.rb +2 -2
  17. data/lib/httpi/version.rb +1 -1
  18. data/spec/fixtures/client_cert.pem +18 -14
  19. data/spec/fixtures/client_key.pem +25 -13
  20. data/spec/httpi/adapter/curb_spec.rb +31 -7
  21. data/spec/httpi/adapter/em_http_spec.rb +23 -21
  22. data/spec/httpi/adapter/excon_spec.rb +28 -118
  23. data/spec/httpi/adapter/http_spec.rb +23 -96
  24. data/spec/httpi/adapter/httpclient_spec.rb +32 -0
  25. data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
  26. data/spec/httpi/adapter/net_http_spec.rb +37 -181
  27. data/spec/httpi/auth/ssl_spec.rb +48 -0
  28. data/spec/httpi/httpi_spec.rb +2 -4
  29. data/spec/integration/curb_spec.rb +20 -0
  30. data/spec/integration/em_http_spec.rb +19 -2
  31. data/spec/integration/excon_spec.rb +67 -1
  32. data/spec/integration/fixtures/ca_all.pem +17 -42
  33. data/spec/integration/fixtures/server.cert +17 -17
  34. data/spec/integration/fixtures/server.key +25 -13
  35. data/spec/integration/http_spec.rb +47 -0
  36. data/spec/integration/httpclient_spec.rb +20 -0
  37. data/spec/integration/net_http_persistent_spec.rb +33 -3
  38. data/spec/integration/net_http_spec.rb +144 -1
  39. data/spec/integration/support/application.rb +3 -2
  40. data/spec/integration/support/server.rb +1 -2
  41. data/spec/spec_helper.rb +0 -2
  42. metadata +15 -43
  43. data/.travis.yml +0 -15
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 613b8bb3b0fa730f0920296081683075b6de1c34164bd347a1d93d5928d4af0b
4
- data.tar.gz: 84d1328228a15c27afee7a4bbe04d3a29079129b7227697c6993728c96b4a4c9
3
+ metadata.gz: b488ad4ac7b6d32a313798d387be88d00976ffe2533a1413836bd7e102cfda83
4
+ data.tar.gz: f555c552fbdfa36b727c75e5bf2b3a9a19559098145ce3f969c94f250380b185
5
5
  SHA512:
6
- metadata.gz: d4ea5d0acbfb93fd0599268946a062cb20d162195469bc92d548b241a75902b4b5f2131a5d95fc21c9165b8cf68058bc156126e265676d083b888558f4e32d35
7
- data.tar.gz: '069622ebb89c624bb74d12a883506af7b38553f016a90c223a91a0230fb3b11115b665bafcdcf8c0f3a26c121abdf817581ff7fcddb68acd727ad9218ead6ba8'
6
+ metadata.gz: fccd5e6e95668a6b49e440eee050a2e8f7e456434e6a973bd2cc8d54c97854c1961fc5e941456ff6e3a4356a03bb6b8a7aad023fd7b8d74f0d73a2e1a18fd682
7
+ data.tar.gz: 825d197e0ccb00ba983aba28a40cb6c0f1789bc6ae9cb3ba82363548330fd66609c5c4e904285038d67de6c95850f1ccaca3901f7698b7317657e754f1035f7d
@@ -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,26 @@
1
+ ### 3.0.0 (2021-10-19)
2
+
3
+ * Improvement: [#225](https://github.com/savonrb/httpi/pull/225) Make rack and socksify dependencies optional.
4
+
5
+ ### 2.5.0 (2021-10-05)
6
+
7
+ * Feature: [#214](https://github.com/savonrb/httpi/pull/214) Add SSL ciphers configuration
8
+ * Improvement: [#227](https://github.com/savonrb/httpi/pull/227) Use GitHub Actions as CI. Require at least Ruby v2.3.
9
+
10
+ ### 2.4.5
11
+
12
+ * Improvement: [#209](https://github.com/savonrb/httpi/pull/209) Drop Travis CI support for Ruby < 2.3.0 and jruby.
13
+ * Feature: [#208](https://github.com/savonrb/httpi/pull/208) Add SSL min/max_version configuration for supporting adapters
14
+ * Improvement: [#206](https://github.com/savonrb/httpi/pull/206) Support for net-http-persistent v3
15
+ * Improvement: [#204](https://github.com/savonrb/httpi/pull/204) Avoid excon warning
16
+
17
+ ### 2.4.4
18
+
19
+ * Improvement: [#197](https://github.com/savonrb/httpi/pull/197) Add support for new write timeout option to all adapters
20
+ * Fix: [#196](https://github.com/savonrb/httpi/pull/196) Fix httpi adapters support for read/open timeout
21
+ * Improvement: [Remove references to broken site](https://github.com/savonrb/httpi/commit/345e5e2b1a4376a7be769f67088a431895de09ad)
22
+ * Fix: [#190](https://github.com/savonrb/httpi/pull/190) Don't convert port to string on Excon adapter
23
+
1
24
  ### 2.4.3
2
25
 
3
26
  * Fix: [#171](https://github.com/savonrb/httpi/pull/171) bug with rubyntlm v0.6.0
data/Gemfile CHANGED
@@ -3,18 +3,20 @@ gemspec
3
3
 
4
4
  gem 'jruby-openssl', :platforms => :jruby
5
5
 
6
- # compatibility restrictions for http clients under existing travis test environments
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, :jruby]
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', '~> 2.8', :require => false
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,23 @@
2
2
 
3
3
  A common interface for Ruby's HTTP libraries.
4
4
 
5
- [Documentation](http://httpirb.com) | [RDoc](http://rubydoc.info/gems/httpi) |
5
+ [Documentation](https://www.rubydoc.info/gems/httpi) |
6
6
  [Mailing list](https://groups.google.com/forum/#!forum/httpirb)
7
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)
12
-
8
+ [![Development](https://github.com/savonrb/httpi/actions/workflows/development.yml/badge.svg)](https://github.com/savonrb/httpi/actions/workflows/development.yml)
13
9
 
14
10
  ## Installation
15
11
 
16
- HTTPI is available through [Rubygems](http://rubygems.org/gems/httpi) and can be installed via:
12
+ HTTPI is available through [Rubygems](https://rubygems.org/gems/httpi) and can be installed via:
17
13
 
18
- ```
19
- $ gem install httpi
20
- ```
14
+ $ gem install httpi
21
15
 
22
16
  or add it to your Gemfile like this:
23
17
 
24
- ```
25
- gem 'httpi', '~> 2.1.0'
26
- ```
27
-
18
+ gem 'httpi', '~> 3.0.0'
28
19
 
29
20
  ## Usage example
30
21
 
31
-
32
22
  ``` ruby
33
23
  require "httpi"
34
24
 
@@ -49,7 +39,21 @@ HTTPI.adapter = :httpclient
49
39
  HTTPI.request(:custom, request)
50
40
  ```
51
41
 
42
+ ### Rack Mock Adapter
43
+
44
+ To use the Rack mock adapter, please add the `rack` gem to your gemfile.
45
+
46
+ ### SOCKS Proxy Support
47
+
48
+ To use the the SOCKS proxy support, please add the `socksify` gem to your gemfile, and add the following code:
49
+
50
+ ``` ruby
51
+ require 'socksify'
52
+ require 'socksify/http'
53
+ ```
54
+
55
+ to your project.
52
56
 
53
57
  ## Documentation
54
58
 
55
- Continue reading at [httpirb.com](http://httpirb.com)
59
+ Continue reading at https://www.rubydoc.info/gems/httpi
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,16 @@ 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.rubyforge_project = s.name
17
- s.license = 'MIT'
15
+ s.required_ruby_version = '>= 2.3'
18
16
 
19
- s.add_dependency 'rack'
20
- s.add_dependency 'socksify'
17
+ s.license = 'MIT'
21
18
 
22
19
  s.add_development_dependency 'rubyntlm', '~> 0.3.2'
23
- s.add_development_dependency 'rake', '~> 10.0'
24
- s.add_development_dependency 'rspec', '~> 2.14'
20
+ s.add_development_dependency 'rake', '~> 13.0'
21
+ s.add_development_dependency 'rspec', '~> 3.5'
25
22
  s.add_development_dependency 'mocha', '~> 0.13'
26
- s.add_development_dependency 'puma', '~> 2.3.2'
23
+ s.add_development_dependency 'puma', '~> 5.0'
27
24
  s.add_development_dependency 'webmock'
28
25
 
29
26
  s.files = `git ls-files`.split("\n")
@@ -72,8 +72,9 @@ module HTTPI
72
72
  def basic_setup
73
73
  @client.url = @request.url.to_s
74
74
  @client.proxy_url = @request.proxy.to_s if @request.proxy
75
- @client.timeout = @request.read_timeout if @request.read_timeout
76
- @client.connect_timeout = @request.open_timeout if @request.open_timeout
75
+ read_or_write_timeout = @request.read_timeout || @request.write_timeout
76
+ @client.timeout_ms = read_or_write_timeout * 1000 if read_or_write_timeout
77
+ @client.connect_timeout_ms = @request.open_timeout * 1000 if @request.open_timeout
77
78
  @client.headers = @request.headers.to_hash
78
79
  @client.verbose = false
79
80
  # cURL workaround
@@ -115,6 +116,7 @@ module HTTPI
115
116
  @client.cert_key = ssl.cert_key_file
116
117
  @client.cert = ssl.cert_file
117
118
  @client.certpassword = ssl.cert_key_password
119
+ @client.set(:ssl_cipher_list, ssl.ciphers.join(':')) if ssl.ciphers
118
120
 
119
121
  @client.ssl_verify_peer = ssl.verify_mode == :peer
120
122
  end
@@ -127,6 +129,9 @@ module HTTPI
127
129
  when :SSLv23 then 2
128
130
  when :SSLv3 then 3
129
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
130
135
  end
131
136
 
132
137
  def respond_with(client)
@@ -69,10 +69,11 @@ module HTTPI
69
69
  end
70
70
 
71
71
  def connection_options
72
- options = {
73
- :connect_timeout => @request.open_timeout,
74
- :inactivity_timeout => @request.read_timeout
75
- }
72
+ options = {}
73
+
74
+ read_or_write_timeout = @request.read_timeout || @request.write_timeout
75
+ options[:inactivity_timeout] = read_or_write_timeout if read_or_write_timeout
76
+ options[:connect_timeout] = @request.open_timeout if @request.open_timeout
76
77
 
77
78
  options[:proxy] = proxy_options if @request.proxy
78
79
 
@@ -41,8 +41,9 @@ module HTTPI
41
41
 
42
42
  opts = {
43
43
  :host => url.host,
44
+ :hostname => url.hostname,
44
45
  :path => url.path,
45
- :port => url.port.to_s,
46
+ :port => url.port,
46
47
  :query => url.query,
47
48
  :scheme => url.scheme,
48
49
  :headers => @request.headers,
@@ -58,6 +59,7 @@ module HTTPI
58
59
  opts[:user], opts[:password] = *@request.auth.credentials if @request.auth.basic?
59
60
  opts[:connect_timeout] = @request.open_timeout if @request.open_timeout
60
61
  opts[:read_timeout] = @request.read_timeout if @request.read_timeout
62
+ opts[:write_timeout] = @request.write_timeout if @request.write_timeout
61
63
  opts[:response_block] = @request.on_body if @request.on_body
62
64
  opts[:proxy] = @request.proxy if @request.proxy
63
65
 
@@ -71,7 +73,10 @@ module HTTPI
71
73
  opts[:ssl_verify_peer] = false
72
74
  end
73
75
 
76
+ opts[:ciphers] = ssl.ciphers if ssl.ciphers
74
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
75
80
 
76
81
  opts
77
82
  end
@@ -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,6 +76,12 @@ module HTTPI
73
76
  client = client.via(@request.proxy.host, @request.proxy.port, @request.proxy.user, @request.proxy.password)
74
77
  end
75
78
 
79
+ timeouts = {}
80
+ timeouts[:connect] = @request.open_timeout if @request.open_timeout
81
+ timeouts[:read] = @request.read_timeout if @request.read_timeout
82
+ timeouts[:write] = @request.write_timeout if @request.write_timeout
83
+ client = client.timeout(timeouts) if timeouts.any?
84
+
76
85
  client.headers(@request.headers)
77
86
  end
78
87
  end
@@ -45,6 +45,7 @@ module HTTPI
45
45
  @client.proxy = @request.proxy if @request.proxy
46
46
  @client.connect_timeout = @request.open_timeout if @request.open_timeout
47
47
  @client.receive_timeout = @request.read_timeout if @request.read_timeout
48
+ @client.send_timeout = @request.write_timeout if @request.write_timeout
48
49
  end
49
50
 
50
51
  def setup_auth
@@ -72,11 +73,15 @@ module HTTPI
72
73
  # Send client-side certificate regardless of state of SSL verify mode
73
74
  @client.ssl_config.client_cert = ssl.cert
74
75
  @client.ssl_config.client_key = ssl.cert_key
76
+ @client.ssl_config.ciphers = ssl.ciphers if ssl.ciphers
75
77
 
76
78
  @client.ssl_config.verify_mode = ssl.openssl_verify_mode
77
79
  end
78
80
 
79
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
80
85
  end
81
86
 
82
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
@@ -155,6 +153,13 @@ module HTTPI
155
153
  @client.use_ssl = @request.ssl?
156
154
  @client.open_timeout = @request.open_timeout if @request.open_timeout
157
155
  @client.read_timeout = @request.read_timeout if @request.read_timeout
156
+ if @request.write_timeout
157
+ if @client.respond_to?(:write_timeout=) # Expected to appear in Ruby 2.6
158
+ @client.write_timeout = @request.write_timeout
159
+ else
160
+ raise NotSupportedError, "Net::HTTP supports write_timeout starting from Ruby 2.6"
161
+ end
162
+ end
158
163
  end
159
164
 
160
165
  def setup_ssl_auth
@@ -170,11 +175,14 @@ module HTTPI
170
175
  # Send client-side certificate regardless of state of SSL verify mode
171
176
  @client.key = ssl.cert_key
172
177
  @client.cert = ssl.cert
178
+ @client.ciphers = ssl.ciphers if ssl.ciphers
173
179
 
174
180
  @client.verify_mode = ssl.openssl_verify_mode
175
181
  end
176
182
 
177
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
178
186
  end
179
187
 
180
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 thread_key
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)
@@ -32,12 +36,12 @@ module HTTPI
32
36
 
33
37
  @client.open_timeout = @request.open_timeout if @request.open_timeout
34
38
  @client.read_timeout = @request.read_timeout if @request.read_timeout
39
+ raise NotSupportedError, "Net::HTTP::Persistent does not support write_timeout" if @request.write_timeout
35
40
  end
36
41
 
37
42
  def thread_key
38
43
  @request.url.host.split(/\W/).reject{|p|p == ""}.join('-')
39
44
  end
40
-
41
45
  end
42
46
  end
43
47
  end
@@ -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
@@ -42,9 +45,27 @@ module HTTPI
42
45
  # Accessor for the ca_path to validate SSL certificates.
43
46
  attr_accessor :ca_cert_path
44
47
 
45
- # ertificate store holds trusted CA certificates used to verify peer certificates.
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/request.rb CHANGED
@@ -11,7 +11,7 @@ module HTTPI
11
11
  class Request
12
12
 
13
13
  # Available attribute writers.
14
- ATTRIBUTES = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout, :follow_redirect, :redirect_limit, :query]
14
+ ATTRIBUTES = [:url, :proxy, :headers, :body, :open_timeout, :read_timeout, :write_timeout, :follow_redirect, :redirect_limit, :query]
15
15
 
16
16
  # Accepts a Hash of +args+ to mass assign attributes and authentication credentials.
17
17
  def initialize(args = {})
@@ -90,7 +90,7 @@ module HTTPI
90
90
  headers["Cookie"] = cookies if cookies
91
91
  end
92
92
 
93
- attr_accessor :open_timeout, :read_timeout
93
+ attr_accessor :open_timeout, :read_timeout, :write_timeout
94
94
  attr_reader :body
95
95
 
96
96
  # Sets a body request given a String or a Hash.
data/lib/httpi/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module HTTPI
2
- VERSION = '2.4.3'
2
+ VERSION = '3.0.0'
3
3
  end
@@ -1,16 +1,20 @@
1
1
  -----BEGIN CERTIFICATE-----
2
- MIICbTCCAdYCCQDC4v8d04615DANBgkqhkiG9w0BAQUFADB7MQswCQYDVQQGEwJE
3
- RTEQMA4GA1UECBMHSGFtYnVyZzEQMA4GA1UEBxMHSGFtYnVyZzEOMAwGA1UEChMF
4
- aHR0cGkxFDASBgNVBAMTC2V4YW1wbGUuY29tMSIwIAYJKoZIhvcNAQkBFhNleGFt
5
- cGxlQGV4YW1wbGUuY29tMB4XDTEwMTAxNTE4NTg0N1oXDTExMTAxNTE4NTg0N1ow
6
- ezELMAkGA1UEBhMCREUxEDAOBgNVBAgTB0hhbWJ1cmcxEDAOBgNVBAcTB0hhbWJ1
7
- cmcxDjAMBgNVBAoTBWh0dHBpMRQwEgYDVQQDEwtleGFtcGxlLmNvbTEiMCAGCSqG
8
- SIb3DQEJARYTZXhhbXBsZUBleGFtcGxlLmNvbTCBnzANBgkqhkiG9w0BAQEFAAOB
9
- jQAwgYkCgYEAvJiaojIFQAbFczXkBmjxpxra9LbQm0VIESFSl8uBSjmG/gmCBwKg
10
- 8O94P3tAjDNClC+fEqBLE37KH4qe76yw7upgRruP5jQzUEL1yCaVtA/DoqgaCxZy
11
- 7VhB2A3f71Zw6kQPt3BOME68fnGsTX65x9XAawCGzGmJSk/Z6wvml1MCAwEAATAN
12
- BgkqhkiG9w0BAQUFAAOBgQCxOyni9LOKf17vUKVG8Y4TBzRYwm8/hlEdVEU3JKG0
13
- /aCCwIJLHl+z+3L4r81IN3+YKrHilqx9K0emboJbBRQklYsv/AE+J44Bq3llRiro
14
- 0e5zwH61jb1j+kxhcxoGiiy8R7hYho24ljuMgFGqtK3kZSP/t9tBLLVp+ItWQ6xX
15
- 5g==
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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
- 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
15
27
  -----END RSA PRIVATE KEY-----