httpi 2.4.2 → 2.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (44) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/development.yml +48 -0
  3. data/CHANGELOG.md +27 -0
  4. data/Gemfile +9 -4
  5. data/README.md +4 -9
  6. data/Rakefile +5 -3
  7. data/httpi.gemspec +5 -5
  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 +11 -2
  11. data/lib/httpi/adapter/http.rb +15 -2
  12. data/lib/httpi/adapter/httpclient.rb +5 -0
  13. data/lib/httpi/adapter/net_http.rb +17 -3
  14. data/lib/httpi/adapter/net_http_persistent.rb +6 -2
  15. data/lib/httpi/auth/ssl.rb +62 -3
  16. data/lib/httpi/logger.rb +6 -1
  17. data/lib/httpi/request.rb +2 -2
  18. data/lib/httpi/version.rb +1 -1
  19. data/spec/fixtures/client_cert.pem +18 -14
  20. data/spec/fixtures/client_key.pem +25 -13
  21. data/spec/httpi/adapter/curb_spec.rb +32 -9
  22. data/spec/httpi/adapter/em_http_spec.rb +23 -21
  23. data/spec/httpi/adapter/excon_spec.rb +28 -118
  24. data/spec/httpi/adapter/http_spec.rb +23 -96
  25. data/spec/httpi/adapter/httpclient_spec.rb +32 -0
  26. data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
  27. data/spec/httpi/adapter/net_http_spec.rb +37 -154
  28. data/spec/httpi/auth/ssl_spec.rb +49 -1
  29. data/spec/httpi/httpi_spec.rb +2 -4
  30. data/spec/integration/curb_spec.rb +20 -0
  31. data/spec/integration/em_http_spec.rb +19 -2
  32. data/spec/integration/excon_spec.rb +174 -0
  33. data/spec/integration/fixtures/ca_all.pem +17 -42
  34. data/spec/integration/fixtures/server.cert +17 -17
  35. data/spec/integration/fixtures/server.key +25 -13
  36. data/spec/integration/http_spec.rb +156 -0
  37. data/spec/integration/httpclient_spec.rb +20 -0
  38. data/spec/integration/net_http_persistent_spec.rb +34 -2
  39. data/spec/integration/net_http_spec.rb +136 -1
  40. data/spec/integration/support/application.rb +3 -2
  41. data/spec/integration/support/server.rb +1 -2
  42. data/spec/spec_helper.rb +0 -2
  43. metadata +16 -15
  44. data/.travis.yml +0 -9
@@ -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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
- IPAFn9KHukdqGXkwEMdErsUaPTy9A1V/aROVEaAY+HJgq/eZAkEA/BP1QMV04WEZ
8
- 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
- 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
- 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
- 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
- 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
- mGSYFu9ZhvZkvQNV8eYrAkBJ+rOIaLDsmbrgkeDruH+B/9yrm4McDtQ/rgnOGYnH
14
- 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
15
27
  -----END RSA PRIVATE KEY-----
@@ -0,0 +1,156 @@
1
+ require "spec_helper"
2
+ require "integration/support/server"
3
+
4
+ describe HTTPI::Adapter::HTTP do
5
+
6
+ subject(:adapter) { :http }
7
+
8
+ context "http requests" do
9
+ before :all do
10
+ @server = IntegrationServer.run
11
+ end
12
+
13
+ after :all do
14
+ @server.stop
15
+ end
16
+
17
+ it "sends and receives HTTP headers" do
18
+ request = HTTPI::Request.new(@server.url + "x-header")
19
+ request.headers["X-Header"] = "HTTPI"
20
+
21
+ response = HTTPI.get(request, adapter)
22
+ expect(response.body).to include("HTTPI")
23
+ end
24
+
25
+ it "it supports headers with multiple values" do
26
+ request = HTTPI::Request.new(@server.url + "cookies")
27
+
28
+ response = HTTPI.get(request, adapter)
29
+ cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
30
+ expect(response.headers["Set-Cookie"]).to eq(cookies)
31
+ end
32
+
33
+ it "it supports read timeout" do
34
+ require "http"
35
+
36
+ request = HTTPI::Request.new(@server.url + "timeout")
37
+ request.read_timeout = 0.5 # seconds
38
+
39
+ expect do
40
+ HTTPI.get(request, adapter)
41
+ end.to raise_exception(HTTP::TimeoutError)
42
+ end
43
+
44
+
45
+ it "executes GET requests" do
46
+ response = HTTPI.get(@server.url, adapter)
47
+ expect(response.body).to eq("get")
48
+ expect(response.headers["Content-Type"]).to eq("text/plain")
49
+ end
50
+
51
+ it "executes POST requests" do
52
+ response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
53
+ expect(response.body).to eq("post")
54
+ expect(response.headers["Content-Type"]).to eq("text/plain")
55
+ end
56
+
57
+ it "executes HEAD requests" do
58
+ response = HTTPI.head(@server.url, adapter)
59
+ expect(response.code).to eq(200)
60
+ expect(response.headers["Content-Type"]).to eq("text/plain")
61
+ end
62
+
63
+ it "executes PUT requests" do
64
+ response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
65
+ expect(response.body).to eq("put")
66
+ expect(response.headers["Content-Type"]).to eq("text/plain")
67
+ end
68
+
69
+ it "executes DELETE requests" do
70
+ response = HTTPI.delete(@server.url, adapter)
71
+ expect(response.body).to eq("delete")
72
+ expect(response.headers["Content-Type"]).to eq("text/plain")
73
+ end
74
+
75
+ it "supports basic authentication" do
76
+ request = HTTPI::Request.new(@server.url + "basic-auth")
77
+ request.auth.basic("admin", "secret")
78
+
79
+ response = HTTPI.get(request, adapter)
80
+ expect(response.body).to eq("basic-auth")
81
+ end
82
+
83
+ it "does not support digest authentication" do
84
+ request = HTTPI::Request.new(@server.url + "digest-auth")
85
+ request.auth.digest("admin", "secret")
86
+
87
+ expect { HTTPI.get(request, adapter) }.
88
+ to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
89
+ end
90
+
91
+ it "does not support ntlm authentication" do
92
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
93
+ request.auth.ntlm("tester", "vReqSoafRe5O")
94
+
95
+ expect { HTTPI.get(request, adapter) }.
96
+ to raise_error(HTTPI::NotSupportedError, /does not support NTLM digest authentication/)
97
+ end
98
+
99
+ it "supports chunked response" do
100
+ skip("Needs investigation")
101
+ request = HTTPI::Request.new(@server.url)
102
+ res = ""
103
+ request.on_body do |body|
104
+ res += body
105
+ end
106
+ response = HTTPI.post(request, adapter)
107
+ expect(res).to eq("post")
108
+ expect(response.body).to eq("")
109
+ end
110
+ end
111
+
112
+ if RUBY_PLATFORM =~ /java/
113
+ pending "Puma Server complains: SSL not supported on JRuby"
114
+ else
115
+ context "https requests" do
116
+ before :all do
117
+ @server = IntegrationServer.run(:ssl => true)
118
+ end
119
+ after :all do
120
+ @server.stop
121
+ end
122
+
123
+ it "raises when no certificate was set up" do
124
+ expect { HTTPI.post(@server.url, "", adapter) }.to raise_error(HTTPI::SSLError)
125
+ end
126
+
127
+ it "works when set up properly" do
128
+ request = HTTPI::Request.new(@server.url)
129
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
130
+
131
+ response = HTTPI.get(request, adapter)
132
+ expect(response.body).to eq("get")
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
153
+ end
154
+ end
155
+
156
+ end
@@ -30,6 +30,17 @@ describe HTTPI::Adapter::HTTPClient do
30
30
  expect(response.headers["Set-Cookie"]).to eq(cookies)
31
31
  end
32
32
 
33
+ it "it supports read timeout" do
34
+ require "httpclient"
35
+
36
+ request = HTTPI::Request.new(@server.url + "timeout")
37
+ request.read_timeout = 0.5 # seconds
38
+
39
+ expect do
40
+ HTTPI.get(request, adapter)
41
+ end.to raise_exception(HTTPClient::ReceiveTimeoutError)
42
+ end
43
+
33
44
  it "executes GET requests" do
34
45
  response = HTTPI.get(@server.url, adapter)
35
46
  expect(response.body).to eq("get")
@@ -110,6 +121,15 @@ describe HTTPI::Adapter::HTTPClient do
110
121
  response = HTTPI.get(request, adapter)
111
122
  expect(response.body).to eq("get")
112
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
113
133
  end
114
134
  end
115
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::NetHTTP do
5
+ describe HTTPI::Adapter::NetHTTPPersistent do
5
6
 
6
7
  subject(:adapter) { :net_http_persistent }
7
8
 
@@ -30,6 +31,17 @@ describe HTTPI::Adapter::NetHTTP do
30
31
  expect(response.headers["Set-Cookie"]).to eq(cookies)
31
32
  end
32
33
 
34
+ it "it supports read timeout" do
35
+ require "net/http/persistent"
36
+
37
+ request = HTTPI::Request.new(@server.url + "timeout")
38
+ request.read_timeout = 0.5 # seconds
39
+
40
+ expect do
41
+ HTTPI.get(request, adapter)
42
+ end.to raise_exception(Net::ReadTimeout)
43
+ end
44
+
33
45
  it "executes GET requests" do
34
46
  response = HTTPI.get(@server.url, adapter)
35
47
  expect(response.body).to eq("get")
@@ -37,7 +49,9 @@ describe HTTPI::Adapter::NetHTTP do
37
49
  end
38
50
 
39
51
  it "executes POST requests" do
40
- response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
52
+ request = HTTPI::Request.new(url: @server.url, body: "<some>xml</some>")
53
+
54
+ response = HTTPI.post(request, adapter)
41
55
  expect(response.body).to eq("post")
42
56
  expect(response.headers["Content-Type"]).to eq("text/plain")
43
57
  end
@@ -68,6 +82,14 @@ describe HTTPI::Adapter::NetHTTP do
68
82
  expect(response.body).to eq("basic-auth")
69
83
  end
70
84
 
85
+ it "does not support ntlm authentication" do
86
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
87
+ request.auth.ntlm("tester", "vReqSoafRe5O")
88
+
89
+ expect { HTTPI.get(request, adapter) }.
90
+ to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
91
+ end
92
+
71
93
  # it does not support digest authentication
72
94
 
73
95
  it "supports chunked response" do
@@ -89,6 +111,7 @@ describe HTTPI::Adapter::NetHTTP do
89
111
  before :all do
90
112
  @server = IntegrationServer.run(:ssl => true)
91
113
  end
114
+
92
115
  after :all do
93
116
  @server.stop
94
117
  end
@@ -101,6 +124,15 @@ describe HTTPI::Adapter::NetHTTP do
101
124
  response = HTTPI.get(request, adapter)
102
125
  expect(response.body).to eq("get")
103
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
104
136
  end
105
137
  end
106
138
 
@@ -14,6 +14,21 @@ describe HTTPI::Adapter::NetHTTP do
14
14
  @server.stop
15
15
  end
16
16
 
17
+ context "when socks is specified" do
18
+ let(:socks_client) { mock("socks_client") }
19
+ let(:request) { HTTPI::Request.new(@server.url) }
20
+
21
+ it "uses Net::HTTP.SOCKSProxy as client" do
22
+ socks_client.expects(:new).with(URI(@server.url).host, URI(@server.url).port).returns(:socks_client_instance)
23
+ Net::HTTP.expects(:SOCKSProxy).with("localhost", 8080).returns socks_client
24
+
25
+ request.proxy = "socks://localhost:8080"
26
+ adapter = HTTPI::Adapter::NetHTTP.new(request)
27
+
28
+ expect(adapter.client).to eq(:socks_client_instance)
29
+ end
30
+ end
31
+
17
32
  it "sends and receives HTTP headers" do
18
33
  request = HTTPI::Request.new(@server.url + "x-header")
19
34
  request.headers["X-Header"] = "HTTPI"
@@ -30,6 +45,17 @@ describe HTTPI::Adapter::NetHTTP do
30
45
  expect(response.headers["Set-Cookie"]).to eq(cookies)
31
46
  end
32
47
 
48
+ it "it supports read timeout" do
49
+ require "net/http"
50
+
51
+ request = HTTPI::Request.new(@server.url + "timeout")
52
+ request.read_timeout = 0.5 # seconds
53
+
54
+ expect do
55
+ HTTPI.get(request, adapter)
56
+ end.to raise_exception(Net::ReadTimeout)
57
+ end
58
+
33
59
  it "executes GET requests" do
34
60
  response = HTTPI.get(@server.url, adapter)
35
61
  expect(response.body).to eq("get")
@@ -60,6 +86,34 @@ describe HTTPI::Adapter::NetHTTP do
60
86
  expect(response.headers["Content-Type"]).to eq("text/plain")
61
87
  end
62
88
 
89
+ context "custom methods" do
90
+ let(:request) {
91
+ HTTPI::Request.new(@server.url).tap do |r|
92
+ r.body = request_body if request_body
93
+ end
94
+ }
95
+ let(:request_body) { nil }
96
+ let(:response) { HTTPI.request(http_method, request, adapter) }
97
+
98
+ shared_examples_for "any supported custom method" do
99
+ specify { response.body.should eq http_method.to_s }
100
+ specify { response.headers["Content-Type"].should eq("text/plain") }
101
+ end
102
+
103
+ context "PATCH method" do
104
+ let(:http_method) { :patch }
105
+ let(:request_body) { "<some>xml</some>" }
106
+
107
+ it_behaves_like "any supported custom method"
108
+ end
109
+
110
+ context "UNSUPPORTED method" do
111
+ let(:http_method) { :unsupported }
112
+
113
+ specify { expect { response }.to raise_error HTTPI::NotSupportedError }
114
+ end
115
+ end
116
+
63
117
  it "supports basic authentication" do
64
118
  request = HTTPI::Request.new(@server.url + "basic-auth")
65
119
  request.auth.basic("admin", "secret")
@@ -68,7 +122,69 @@ describe HTTPI::Adapter::NetHTTP do
68
122
  expect(response.body).to eq("basic-auth")
69
123
  end
70
124
 
71
- # it does not support digest authentication
125
+ it "does not support digest authentication" do
126
+ request = HTTPI::Request.new(@server.url + "digest-auth")
127
+ request.auth.digest("admin", "secret")
128
+
129
+ expect { HTTPI.get(request, adapter) }.
130
+ to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
131
+ end
132
+
133
+ it "supports ntlm authentication" do
134
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
135
+ request.auth.ntlm("tester", "vReqSoafRe5O")
136
+
137
+ response = HTTPI.get(request, adapter)
138
+ expect(response.body).to eq("ntlm-auth")
139
+ end
140
+
141
+ it "does not support ntlm authentication when Net::NTLM is not available" do
142
+ Net.expects(:const_defined?).with(:NTLM).returns false
143
+
144
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
145
+ request.auth.ntlm("testing", "failures")
146
+
147
+ expect { HTTPI.get(request, adapter) }.
148
+ to raise_error(HTTPI::NotSupportedError, /Net::NTLM is not available/)
149
+ end
150
+
151
+ it "does not require ntlm when ntlm authenication is not requested" do
152
+ HTTPI::Adapter::NetHTTP.any_instance.stubs(:check_net_ntlm_version!).raises(RuntimeError)
153
+ request = HTTPI::Request.new(@server.url)
154
+ expect(request.auth.ntlm?).to be false
155
+
156
+ # make sure a request doesn't call ntlm check if we don't ask for it.
157
+ expect { HTTPI.get(request, adapter) }.not_to raise_error
158
+ HTTPI::Adapter::NetHTTP.any_instance.unstub(:check_net_ntlm_version!)
159
+ end
160
+
161
+ it "does check ntlm when ntlm authentication is requested" do
162
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
163
+ request.auth.ntlm("tester", "vReqSoafRe5O")
164
+
165
+ expect { HTTPI.get(request, adapter) }.not_to raise_error
166
+
167
+ # the check should also verify that the version of ntlm is supported and still fail if it isn't
168
+ HTTPI::Adapter::NetHTTP.any_instance.stubs(:ntlm_version).returns("0.1.1")
169
+
170
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
171
+ request.auth.ntlm("tester", "vReqSoafRe5O")
172
+
173
+ expect { HTTPI.get(request, adapter) }.to raise_error(ArgumentError, /Invalid version/)
174
+
175
+ HTTPI::Adapter::NetHTTP.any_instance.unstub(:ntlm_version)
176
+ end
177
+
178
+ it "does not crash when authenticate header is missing (on second request)" do
179
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
180
+ request.auth.ntlm("tester", "vReqSoafRe5O")
181
+
182
+ expect { HTTPI.get(request, adapter) }.
183
+ to_not raise_error
184
+
185
+ expect { HTTPI.get(request, adapter) }.
186
+ to_not raise_error
187
+ end
72
188
 
73
189
  it "supports chunked response" do
74
190
  request = HTTPI::Request.new(@server.url)
@@ -101,6 +217,25 @@ describe HTTPI::Adapter::NetHTTP do
101
217
  response = HTTPI.get(request, adapter)
102
218
  expect(response.body).to eq("get")
103
219
  end
220
+
221
+ it "works with min_version/max_version" do
222
+ request = HTTPI::Request.new(@server.url)
223
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
224
+ request.auth.ssl.min_version = :TLS1_2
225
+ request.auth.ssl.max_version = :TLS1_2
226
+
227
+ response = HTTPI.get(request, adapter)
228
+ expect(response.body).to eq("get")
229
+ end
230
+
231
+ it "works with ciphers" do
232
+ request = HTTPI::Request.new(@server.url)
233
+ request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
234
+ request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
235
+
236
+ response = HTTPI.get(request, adapter)
237
+ expect(response.body).to eq("get")
238
+ end
104
239
  end
105
240
  end
106
241
 
@@ -15,9 +15,10 @@ class IntegrationServer
15
15
  }
16
16
  end
17
17
 
18
- map "/repeat" do
18
+ map "/timeout" do
19
19
  run lambda { |env|
20
- IntegrationServer.respond_with :body => env["rack.input"].read
20
+ sleep 2
21
+ IntegrationServer.respond_with "done"
21
22
  }
22
23
  end
23
24
 
@@ -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::VERIFY_PEER
78
+ context.verify_mode = Puma::MiniSSL::VERIFY_NONE
80
79
 
81
80
  context
82
81
  end
data/spec/spec_helper.rb CHANGED
@@ -3,9 +3,7 @@ Bundler.setup(:default, :development)
3
3
 
4
4
  unless RUBY_PLATFORM =~ /java/
5
5
  require 'simplecov'
6
- require 'coveralls'
7
6
 
8
- SimpleCov.formatter = Coveralls::SimpleCov::Formatter
9
7
  SimpleCov.start do
10
8
  add_filter 'spec'
11
9
  end
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: 2.4.2
4
+ version: 2.5.0
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: 2016-04-29 00:00:00.000000000 Z
12
+ date: 2021-10-05 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -59,28 +59,28 @@ dependencies:
59
59
  requirements:
60
60
  - - "~>"
61
61
  - !ruby/object:Gem::Version
62
- version: '10.0'
62
+ version: '13.0'
63
63
  type: :development
64
64
  prerelease: false
65
65
  version_requirements: !ruby/object:Gem::Requirement
66
66
  requirements:
67
67
  - - "~>"
68
68
  - !ruby/object:Gem::Version
69
- version: '10.0'
69
+ version: '13.0'
70
70
  - !ruby/object:Gem::Dependency
71
71
  name: rspec
72
72
  requirement: !ruby/object:Gem::Requirement
73
73
  requirements:
74
74
  - - "~>"
75
75
  - !ruby/object:Gem::Version
76
- version: '2.14'
76
+ version: '3.5'
77
77
  type: :development
78
78
  prerelease: false
79
79
  version_requirements: !ruby/object:Gem::Requirement
80
80
  requirements:
81
81
  - - "~>"
82
82
  - !ruby/object:Gem::Version
83
- version: '2.14'
83
+ version: '3.5'
84
84
  - !ruby/object:Gem::Dependency
85
85
  name: mocha
86
86
  requirement: !ruby/object:Gem::Requirement
@@ -101,14 +101,14 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: 2.3.2
104
+ version: '5.0'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: 2.3.2
111
+ version: '5.0'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: webmock
114
114
  requirement: !ruby/object:Gem::Requirement
@@ -129,9 +129,9 @@ executables: []
129
129
  extensions: []
130
130
  extra_rdoc_files: []
131
131
  files:
132
+ - ".github/workflows/development.yml"
132
133
  - ".gitignore"
133
134
  - ".rspec"
134
- - ".travis.yml"
135
135
  - CHANGELOG.md
136
136
  - Gemfile
137
137
  - LICENSE
@@ -186,9 +186,11 @@ files:
186
186
  - spec/httpi/response_spec.rb
187
187
  - spec/integration/curb_spec.rb
188
188
  - spec/integration/em_http_spec.rb
189
+ - spec/integration/excon_spec.rb
189
190
  - spec/integration/fixtures/ca_all.pem
190
191
  - spec/integration/fixtures/server.cert
191
192
  - spec/integration/fixtures/server.key
193
+ - spec/integration/http_spec.rb
192
194
  - spec/integration/httpclient_spec.rb
193
195
  - spec/integration/net_http_persistent_spec.rb
194
196
  - spec/integration/net_http_spec.rb
@@ -202,7 +204,7 @@ homepage: http://github.com/savonrb/httpi
202
204
  licenses:
203
205
  - MIT
204
206
  metadata: {}
205
- post_install_message:
207
+ post_install_message:
206
208
  rdoc_options: []
207
209
  require_paths:
208
210
  - lib
@@ -210,16 +212,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
210
212
  requirements:
211
213
  - - ">="
212
214
  - !ruby/object:Gem::Version
213
- version: 1.9.2
215
+ version: '2.3'
214
216
  required_rubygems_version: !ruby/object:Gem::Requirement
215
217
  requirements:
216
218
  - - ">="
217
219
  - !ruby/object:Gem::Version
218
220
  version: '0'
219
221
  requirements: []
220
- rubyforge_project: httpi
221
- rubygems_version: 2.5.1
222
- signing_key:
222
+ rubygems_version: 3.2.7
223
+ signing_key:
223
224
  specification_version: 4
224
225
  summary: Common interface for Ruby's HTTP libraries
225
226
  test_files: []
data/.travis.yml DELETED
@@ -1,9 +0,0 @@
1
- language: "ruby"
2
- script: "bundle exec rake ci"
3
- sudo: false
4
- rvm:
5
- - 2.0.0
6
- - 2.1.8
7
- - 2.2.4
8
- - 2.3.0
9
- - jruby