httpi 2.4.1 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (50) hide show
  1. checksums.yaml +5 -5
  2. data/.github/workflows/development.yml +48 -0
  3. data/CHANGELOG.md +45 -0
  4. data/Gemfile +10 -5
  5. data/README.md +20 -16
  6. data/Rakefile +5 -3
  7. data/UPDATING.md +7 -0
  8. data/httpi.gemspec +6 -7
  9. data/lib/httpi/adapter/curb.rb +8 -2
  10. data/lib/httpi/adapter/em_http.rb +5 -4
  11. data/lib/httpi/adapter/excon.rb +17 -5
  12. data/lib/httpi/adapter/http.rb +15 -2
  13. data/lib/httpi/adapter/httpclient.rb +16 -4
  14. data/lib/httpi/adapter/net_http.rb +42 -16
  15. data/lib/httpi/adapter/net_http_persistent.rb +6 -2
  16. data/lib/httpi/adapter/rack.rb +13 -6
  17. data/lib/httpi/auth/ssl.rb +68 -3
  18. data/lib/httpi/logger.rb +6 -1
  19. data/lib/httpi/request.rb +12 -5
  20. data/lib/httpi/response.rb +2 -0
  21. data/lib/httpi/version.rb +1 -1
  22. data/lib/httpi.rb +4 -4
  23. data/spec/fixtures/client_cert.pem +18 -14
  24. data/spec/fixtures/client_key.pem +25 -13
  25. data/spec/httpi/adapter/curb_spec.rb +36 -10
  26. data/spec/httpi/adapter/em_http_spec.rb +23 -21
  27. data/spec/httpi/adapter/excon_spec.rb +28 -90
  28. data/spec/httpi/adapter/http_spec.rb +23 -96
  29. data/spec/httpi/adapter/httpclient_spec.rb +46 -4
  30. data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
  31. data/spec/httpi/adapter/net_http_spec.rb +39 -99
  32. data/spec/httpi/adapter/rack_spec.rb +6 -8
  33. data/spec/httpi/auth/ssl_spec.rb +49 -1
  34. data/spec/httpi/httpi_spec.rb +16 -4
  35. data/spec/httpi/request_spec.rb +5 -0
  36. data/spec/integration/curb_spec.rb +20 -0
  37. data/spec/integration/em_http_spec.rb +19 -2
  38. data/spec/integration/excon_spec.rb +174 -0
  39. data/spec/integration/fixtures/ca_all.pem +17 -42
  40. data/spec/integration/fixtures/server.cert +17 -17
  41. data/spec/integration/fixtures/server.key +25 -13
  42. data/spec/integration/http_spec.rb +156 -0
  43. data/spec/integration/httpclient_spec.rb +20 -0
  44. data/spec/integration/net_http_persistent_spec.rb +34 -2
  45. data/spec/integration/net_http_spec.rb +144 -1
  46. data/spec/integration/support/application.rb +4 -2
  47. data/spec/integration/support/server.rb +1 -2
  48. data/spec/spec_helper.rb +0 -2
  49. metadata +31 -29
  50. data/.travis.yml +0 -8
@@ -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,42 @@ 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
+
97
+ subject(:response) { HTTPI.request(http_method, request, adapter) }
98
+
99
+ shared_examples_for "any supported custom method" do
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
109
+ end
110
+
111
+ context "PATCH method" do
112
+ let(:http_method) { :patch }
113
+ let(:request_body) { "<some>xml</some>" }
114
+
115
+ it_behaves_like "any supported custom method"
116
+ end
117
+
118
+ context "UNSUPPORTED method" do
119
+ let(:http_method) { :unsupported }
120
+
121
+ specify { expect { response }.to raise_error HTTPI::NotSupportedError }
122
+ end
123
+ end
124
+
63
125
  it "supports basic authentication" do
64
126
  request = HTTPI::Request.new(@server.url + "basic-auth")
65
127
  request.auth.basic("admin", "secret")
@@ -68,7 +130,69 @@ describe HTTPI::Adapter::NetHTTP do
68
130
  expect(response.body).to eq("basic-auth")
69
131
  end
70
132
 
71
- # it does not support digest authentication
133
+ it "does not support digest authentication" do
134
+ request = HTTPI::Request.new(@server.url + "digest-auth")
135
+ request.auth.digest("admin", "secret")
136
+
137
+ expect { HTTPI.get(request, adapter) }.
138
+ to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
139
+ end
140
+
141
+ it "supports ntlm authentication" do
142
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
143
+ request.auth.ntlm("tester", "vReqSoafRe5O")
144
+
145
+ response = HTTPI.get(request, adapter)
146
+ expect(response.body).to eq("ntlm-auth")
147
+ end
148
+
149
+ it "does not support ntlm authentication when Net::NTLM is not available" do
150
+ Net.expects(:const_defined?).with(:NTLM).returns false
151
+
152
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
153
+ request.auth.ntlm("testing", "failures")
154
+
155
+ expect { HTTPI.get(request, adapter) }.
156
+ to raise_error(HTTPI::NotSupportedError, /Net::NTLM is not available/)
157
+ end
158
+
159
+ it "does not require ntlm when ntlm authenication is not requested" do
160
+ HTTPI::Adapter::NetHTTP.any_instance.stubs(:check_net_ntlm_version!).raises(RuntimeError)
161
+ request = HTTPI::Request.new(@server.url)
162
+ expect(request.auth.ntlm?).to be false
163
+
164
+ # make sure a request doesn't call ntlm check if we don't ask for it.
165
+ expect { HTTPI.get(request, adapter) }.not_to raise_error
166
+ HTTPI::Adapter::NetHTTP.any_instance.unstub(:check_net_ntlm_version!)
167
+ end
168
+
169
+ it "does check ntlm when ntlm authentication is requested" do
170
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
171
+ request.auth.ntlm("tester", "vReqSoafRe5O")
172
+
173
+ expect { HTTPI.get(request, adapter) }.not_to raise_error
174
+
175
+ # the check should also verify that the version of ntlm is supported and still fail if it isn't
176
+ HTTPI::Adapter::NetHTTP.any_instance.stubs(:ntlm_version).returns("0.1.1")
177
+
178
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
179
+ request.auth.ntlm("tester", "vReqSoafRe5O")
180
+
181
+ expect { HTTPI.get(request, adapter) }.to raise_error(ArgumentError, /Invalid version/)
182
+
183
+ HTTPI::Adapter::NetHTTP.any_instance.unstub(:ntlm_version)
184
+ end
185
+
186
+ it "does not crash when authenticate header is missing (on second request)" do
187
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
188
+ request.auth.ntlm("tester", "vReqSoafRe5O")
189
+
190
+ expect { HTTPI.get(request, adapter) }.
191
+ to_not raise_error
192
+
193
+ expect { HTTPI.get(request, adapter) }.
194
+ to_not raise_error
195
+ end
72
196
 
73
197
  it "supports chunked response" do
74
198
  request = HTTPI::Request.new(@server.url)
@@ -101,6 +225,25 @@ describe HTTPI::Adapter::NetHTTP do
101
225
  response = HTTPI.get(request, adapter)
102
226
  expect(response.body).to eq("get")
103
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
104
247
  end
105
248
  end
106
249
 
@@ -1,3 +1,4 @@
1
+ require 'rack'
1
2
  require "rack/builder"
2
3
 
3
4
  class IntegrationServer
@@ -14,9 +15,10 @@ class IntegrationServer
14
15
  }
15
16
  end
16
17
 
17
- map "/repeat" do
18
+ map "/timeout" do
18
19
  run lambda { |env|
19
- IntegrationServer.respond_with :body => env["rack.input"].read
20
+ sleep 2
21
+ IntegrationServer.respond_with "done"
20
22
  }
21
23
  end
22
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,30 +1,16 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: httpi
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.4.1
4
+ version: 3.0.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: 2015-06-18 00:00:00.000000000 Z
12
+ date: 2021-10-18 00:00:00.000000000 Z
13
13
  dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rack
16
- requirement: !ruby/object:Gem::Requirement
17
- requirements:
18
- - - ">="
19
- - !ruby/object:Gem::Version
20
- version: '0'
21
- type: :runtime
22
- prerelease: false
23
- version_requirements: !ruby/object:Gem::Requirement
24
- requirements:
25
- - - ">="
26
- - !ruby/object:Gem::Version
27
- version: '0'
28
14
  - !ruby/object:Gem::Dependency
29
15
  name: rubyntlm
30
16
  requirement: !ruby/object:Gem::Requirement
@@ -45,28 +31,28 @@ dependencies:
45
31
  requirements:
46
32
  - - "~>"
47
33
  - !ruby/object:Gem::Version
48
- version: '10.0'
34
+ version: '13.0'
49
35
  type: :development
50
36
  prerelease: false
51
37
  version_requirements: !ruby/object:Gem::Requirement
52
38
  requirements:
53
39
  - - "~>"
54
40
  - !ruby/object:Gem::Version
55
- version: '10.0'
41
+ version: '13.0'
56
42
  - !ruby/object:Gem::Dependency
57
43
  name: rspec
58
44
  requirement: !ruby/object:Gem::Requirement
59
45
  requirements:
60
46
  - - "~>"
61
47
  - !ruby/object:Gem::Version
62
- version: '2.14'
48
+ version: '3.5'
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: '2.14'
55
+ version: '3.5'
70
56
  - !ruby/object:Gem::Dependency
71
57
  name: mocha
72
58
  requirement: !ruby/object:Gem::Requirement
@@ -87,28 +73,43 @@ dependencies:
87
73
  requirements:
88
74
  - - "~>"
89
75
  - !ruby/object:Gem::Version
90
- version: 2.3.2
76
+ version: '5.0'
91
77
  type: :development
92
78
  prerelease: false
93
79
  version_requirements: !ruby/object:Gem::Requirement
94
80
  requirements:
95
81
  - - "~>"
96
82
  - !ruby/object:Gem::Version
97
- version: 2.3.2
83
+ version: '5.0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: webmock
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
98
  description: Common interface for Ruby's HTTP libraries
99
99
  email: me@rubiii.com
100
100
  executables: []
101
101
  extensions: []
102
102
  extra_rdoc_files: []
103
103
  files:
104
+ - ".github/workflows/development.yml"
104
105
  - ".gitignore"
105
106
  - ".rspec"
106
- - ".travis.yml"
107
107
  - CHANGELOG.md
108
108
  - Gemfile
109
109
  - LICENSE
110
110
  - README.md
111
111
  - Rakefile
112
+ - UPDATING.md
112
113
  - httpi.gemspec
113
114
  - lib/httpi.rb
114
115
  - lib/httpi/adapter.rb
@@ -158,9 +159,11 @@ files:
158
159
  - spec/httpi/response_spec.rb
159
160
  - spec/integration/curb_spec.rb
160
161
  - spec/integration/em_http_spec.rb
162
+ - spec/integration/excon_spec.rb
161
163
  - spec/integration/fixtures/ca_all.pem
162
164
  - spec/integration/fixtures/server.cert
163
165
  - spec/integration/fixtures/server.key
166
+ - spec/integration/http_spec.rb
164
167
  - spec/integration/httpclient_spec.rb
165
168
  - spec/integration/net_http_persistent_spec.rb
166
169
  - spec/integration/net_http_spec.rb
@@ -174,7 +177,7 @@ homepage: http://github.com/savonrb/httpi
174
177
  licenses:
175
178
  - MIT
176
179
  metadata: {}
177
- post_install_message:
180
+ post_install_message:
178
181
  rdoc_options: []
179
182
  require_paths:
180
183
  - lib
@@ -182,16 +185,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
182
185
  requirements:
183
186
  - - ">="
184
187
  - !ruby/object:Gem::Version
185
- version: 1.9.2
188
+ version: '2.3'
186
189
  required_rubygems_version: !ruby/object:Gem::Requirement
187
190
  requirements:
188
191
  - - ">="
189
192
  - !ruby/object:Gem::Version
190
193
  version: '0'
191
194
  requirements: []
192
- rubyforge_project: httpi
193
- rubygems_version: 2.4.8
194
- signing_key:
195
+ rubygems_version: 3.2.7
196
+ signing_key:
195
197
  specification_version: 4
196
198
  summary: Common interface for Ruby's HTTP libraries
197
199
  test_files: []
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- language: "ruby"
2
- script: "bundle exec rake ci"
3
- rvm:
4
- - 1.9.3
5
- - 2.0
6
- - 2.1
7
- - 2.2
8
- - jruby-19mode