httpi 2.4.1 → 3.0.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 (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
@@ -1,101 +1,28 @@
1
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 "executes GET requests" do
26
- response = HTTPI.get(@server.url, adapter)
27
- expect(response.body).to eq("get")
28
- expect(response.headers["Content-Type"]).to eq("text/plain")
29
- end
30
-
31
- it "executes POST requests" do
32
- response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
33
- expect(response.body).to eq("post")
34
- expect(response.headers["Content-Type"]).to eq("text/plain")
35
- end
36
-
37
- it "executes HEAD requests" do
38
- response = HTTPI.head(@server.url, adapter)
39
- expect(response.code).to eq(200)
40
- expect(response.headers["Content-Type"]).to eq("text/plain")
41
- end
42
-
43
- it "executes PUT requests" do
44
- response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
45
- expect(response.body).to eq("put")
46
- expect(response.headers["Content-Type"]).to eq("text/plain")
47
- end
48
-
49
- it "executes DELETE requests" do
50
- response = HTTPI.delete(@server.url, adapter)
51
- expect(response.body).to eq("delete")
52
- expect(response.headers["Content-Type"]).to eq("text/plain")
53
- end
54
-
55
- it "supports basic authentication" do
56
- request = HTTPI::Request.new(@server.url + "basic-auth")
57
- request.auth.basic("admin", "secret")
58
-
59
- response = HTTPI.get(request, adapter)
60
- expect(response.body).to eq("basic-auth")
61
- end
62
-
63
- it "does not support digest authentication" do
64
- request = HTTPI::Request.new(@server.url + "digest-auth")
65
- request.auth.digest("admin", "secret")
66
-
67
- expect { HTTPI.get(request, adapter) }.
68
- to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
69
- end
70
-
71
- it "does not support ntlm authentication" do
72
- request = HTTPI::Request.new(@server.url + "ntlm-auth")
73
- request.auth.ntlm("tester", "vReqSoafRe5O")
74
-
75
- expect { HTTPI.get(request, adapter) }.
76
- to raise_error(HTTPI::NotSupportedError, /does not support NTLM digest authentication/)
77
- end
78
- end
79
-
80
- if RUBY_PLATFORM =~ /java/
81
- pending "Puma Server complains: SSL not supported on JRuby"
82
- else
83
- context "https requests" do
84
- before :all do
85
- @server = IntegrationServer.run(:ssl => true)
86
- end
87
- after :all do
88
- @server.stop
89
- end
90
-
91
- it "works when set up properly" do
92
- request = HTTPI::Request.new(@server.url)
93
- request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
94
-
95
- response = HTTPI.get(request, adapter)
96
- expect(response.body).to eq("get")
2
+ require "httpi/adapter/http"
3
+ require "httpi/request"
4
+
5
+ begin
6
+ HTTPI::Adapter.load_adapter(:http)
7
+
8
+ describe HTTPI::Adapter::HTTP do
9
+ let(:adapter) { HTTPI::Adapter::HTTP.new(request) }
10
+ let(:request) { HTTPI::Request.new("http://example.com") }
11
+
12
+ describe "settings" do
13
+ describe "connect_timeout, read_timeout, write_timeout" do
14
+ it "are being set on the client" do
15
+ request.open_timeout = 30
16
+ request.read_timeout = 40
17
+ request.write_timeout = 50
18
+
19
+ expect(adapter.client.default_options.timeout_options).to eq(
20
+ connect_timeout: 30,
21
+ read_timeout: 40,
22
+ write_timeout: 50
23
+ )
24
+ end
97
25
  end
98
26
  end
99
27
  end
100
-
101
28
  end
@@ -1,6 +1,7 @@
1
1
  require "spec_helper"
2
2
  require "httpi/adapter/httpclient"
3
3
  require "httpi/request"
4
+ require "integration/support/server"
4
5
 
5
6
  HTTPI::Adapter.load_adapter(:httpclient)
6
7
 
@@ -10,6 +11,14 @@ describe HTTPI::Adapter::HTTPClient do
10
11
  let(:ssl_config) { HTTPClient::SSLConfig.any_instance }
11
12
  let(:request) { HTTPI::Request.new("http://example.com") }
12
13
 
14
+ before :all do
15
+ @server = IntegrationServer.run
16
+ end
17
+
18
+ after :all do
19
+ @server.stop
20
+ end
21
+
13
22
  describe "#request(:get)" do
14
23
  it "returns a valid HTTPI::Response" do
15
24
  httpclient_expects(:get)
@@ -91,6 +100,20 @@ describe HTTPI::Adapter::HTTPClient do
91
100
  end
92
101
  end
93
102
 
103
+ describe "send_timeout" do
104
+ it "is not set unless specified" do
105
+ httpclient.expects(:send_timeout=).never
106
+ adapter.request(:get)
107
+ end
108
+
109
+ it "is set if specified" do
110
+ request.write_timeout = 30
111
+
112
+ httpclient.expects(:send_timeout=).with(30)
113
+ adapter.request(:get)
114
+ end
115
+ end
116
+
94
117
  describe "set_auth" do
95
118
  it "is set for HTTP basic auth" do
96
119
  request.auth.basic "username", "password"
@@ -118,6 +141,13 @@ describe HTTPI::Adapter::HTTPClient do
118
141
 
119
142
  adapter.request(:get)
120
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
121
151
  end
122
152
 
123
153
  context "(for SSL client auth)" do
@@ -155,6 +185,17 @@ describe HTTPI::Adapter::HTTPClient do
155
185
 
156
186
  adapter.request(:get)
157
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
158
199
  end
159
200
 
160
201
  context "(for SSL client auth with a verify mode of :none with no certs provided)" do
@@ -174,11 +215,12 @@ describe HTTPI::Adapter::HTTPClient do
174
215
  end
175
216
  end
176
217
 
177
- it "does not support NTLM authentication" do
178
- request.auth.ntlm("tester", "vReqSoafRe5O")
218
+ it "supports NTLM authentication" do
219
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
179
220
 
180
- expect { adapter.request(:get) }.
181
- to raise_error(HTTPI::NotSupportedError, /adapter does not support NTLM authentication/)
221
+ request.auth.ntlm("tester", "vReqSoafRe5O")
222
+ response = HTTPI.get(request, :httpclient)
223
+ expect(response.body).to eq("ntlm-auth")
182
224
  end
183
225
 
184
226
  def httpclient_expects(method)
@@ -1,96 +1,46 @@
1
1
  require "spec_helper"
2
- require "integration/support/server"
2
+ require "httpi/adapter/net_http_persistent"
3
+ require "httpi/request"
3
4
 
4
- describe HTTPI::Adapter::NetHTTPPersistent do
5
+ begin
6
+ HTTPI::Adapter.load_adapter(:net_http_persistent)
5
7
 
6
- subject(:adapter) { :net_http_persistent }
8
+ describe HTTPI::Adapter::NetHTTPPersistent do
9
+ let(:adapter) { HTTPI::Adapter::NetHTTPPersistent.new(request) }
10
+ let(:request) { HTTPI::Request.new("http://example.com") }
7
11
 
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 "executes GET requests" do
26
- response = HTTPI.get(@server.url, adapter)
27
- expect(response.body).to eq("get")
28
- expect(response.headers["Content-Type"]).to eq("text/plain")
29
- end
30
-
31
- it "executes POST requests" do
32
- response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
33
- expect(response.body).to eq("post")
34
- expect(response.headers["Content-Type"]).to eq("text/plain")
35
- end
36
-
37
- it "executes HEAD requests" do
38
- response = HTTPI.head(@server.url, adapter)
39
- expect(response.code).to eq(200)
40
- expect(response.headers["Content-Type"]).to eq("text/plain")
41
- end
42
-
43
- it "executes PUT requests" do
44
- response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
45
- expect(response.body).to eq("put")
46
- expect(response.headers["Content-Type"]).to eq("text/plain")
47
- end
48
-
49
- it "executes DELETE requests" do
50
- response = HTTPI.delete(@server.url, adapter)
51
- expect(response.body).to eq("delete")
52
- expect(response.headers["Content-Type"]).to eq("text/plain")
53
- end
54
-
55
- it "supports basic authentication" do
56
- request = HTTPI::Request.new(@server.url + "basic-auth")
57
- request.auth.basic("admin", "secret")
12
+ let(:response) {
13
+ Object.new.tap do |r|
14
+ r.stubs(:code).returns(200)
15
+ r.stubs(:body).returns("abc")
16
+ r.stubs(:to_hash).returns({"Content-Length" => "3"})
17
+ end
18
+ }
58
19
 
59
- response = HTTPI.get(request, adapter)
60
- expect(response.body).to eq("basic-auth")
20
+ before do
21
+ Net::HTTP::Persistent.any_instance.stubs(:start).returns(response)
61
22
  end
62
23
 
63
- it "does not support ntlm authentication" do
64
- request = HTTPI::Request.new(@server.url + "ntlm-auth")
65
- request.auth.ntlm("tester", "vReqSoafRe5O")
24
+ describe "settings" do
25
+ describe "open_timeout, read_timeout" do
26
+ it "are being set on the client" do
27
+ request.open_timeout = 30
28
+ request.read_timeout = 40
66
29
 
67
- expect { HTTPI.get(request, adapter) }.
68
- to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
69
- end
70
- end
71
-
72
- # it does not support digest auth
30
+ adapter.client.expects(:open_timeout=).with(30)
31
+ adapter.client.expects(:read_timeout=).with(40)
73
32
 
74
- if RUBY_PLATFORM =~ /java/
75
- pending "Puma Server complains: SSL not supported on JRuby"
76
- else
77
- context "https requests" do
78
- before :all do
79
- @server = IntegrationServer.run(:ssl => true)
33
+ adapter.request(:get)
34
+ end
80
35
  end
81
- after :all do
82
- @server.stop
83
- end
84
-
85
- # it does not raise when no certificate was set up
86
- it "works when set up properly" do
87
- request = HTTPI::Request.new(@server.url)
88
- request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
89
36
 
90
- response = HTTPI.get(request, adapter)
91
- expect(response.body).to eq("get")
37
+ describe "write_timeout" do
38
+ it "is not supported" do
39
+ request.write_timeout = 50
40
+ expect { adapter.request(:get) }
41
+ .to raise_error(HTTPI::NotSupportedError, /write_timeout/)
42
+ end
92
43
  end
93
44
  end
94
45
  end
95
-
96
46
  end
@@ -1,114 +1,54 @@
1
1
  require "spec_helper"
2
- require "integration/support/server"
2
+ require "httpi/adapter/net_http"
3
+ require "httpi/request"
3
4
 
4
- describe HTTPI::Adapter::NetHTTP do
5
+ begin
6
+ HTTPI::Adapter.load_adapter(:net_http)
5
7
 
6
- subject(:adapter) { :net_http }
8
+ describe HTTPI::Adapter::NetHTTP do
9
+ let(:adapter) { HTTPI::Adapter::NetHTTP.new(request) }
10
+ let(:request) { HTTPI::Request.new("http://example.com") }
7
11
 
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 "executes GET requests" do
26
- response = HTTPI.get(@server.url, adapter)
27
- expect(response.body).to eq("get")
28
- expect(response.headers["Content-Type"]).to eq("text/plain")
29
- end
30
-
31
- it "executes POST requests" do
32
- response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
33
- expect(response.body).to eq("post")
34
- expect(response.headers["Content-Type"]).to eq("text/plain")
35
- end
36
-
37
- it "executes HEAD requests" do
38
- response = HTTPI.head(@server.url, adapter)
39
- expect(response.code).to eq(200)
40
- expect(response.headers["Content-Type"]).to eq("text/plain")
41
- end
42
-
43
- it "executes PUT requests" do
44
- response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
45
- expect(response.body).to eq("put")
46
- expect(response.headers["Content-Type"]).to eq("text/plain")
47
- end
48
-
49
- it "executes DELETE requests" do
50
- response = HTTPI.delete(@server.url, adapter)
51
- expect(response.body).to eq("delete")
52
- expect(response.headers["Content-Type"]).to eq("text/plain")
53
- end
54
-
55
- it "supports basic authentication" do
56
- request = HTTPI::Request.new(@server.url + "basic-auth")
57
- request.auth.basic("admin", "secret")
58
-
59
- response = HTTPI.get(request, adapter)
60
- expect(response.body).to eq("basic-auth")
61
- end
62
-
63
- it "does not support digest authentication" do
64
- request = HTTPI::Request.new(@server.url + "digest-auth")
65
- request.auth.digest("admin", "secret")
66
-
67
- expect { HTTPI.get(request, adapter) }.
68
- to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
69
- end
70
-
71
- it "supports ntlm authentication" do
72
- request = HTTPI::Request.new(@server.url + "ntlm-auth")
73
- request.auth.ntlm("tester", "vReqSoafRe5O")
12
+ let(:response) {
13
+ Object.new.tap do |r|
14
+ r.stubs(:code).returns(200)
15
+ r.stubs(:body).returns("abc")
16
+ r.stubs(:to_hash).returns({"Content-Length" => "3"})
17
+ end
18
+ }
74
19
 
75
- response = HTTPI.get(request, adapter)
76
- expect(response.body).to eq("ntlm-auth")
20
+ before do
21
+ Net::HTTP.any_instance.stubs(:start).returns(response)
77
22
  end
78
23
 
79
- it 'does not support ntlm authentication when Net::NTLM is not available' do
80
- Net.expects(:const_defined?).with(:NTLM).returns false
24
+ describe "settings" do
25
+ describe "open_timeout, read_timeout" do
26
+ it "are being set on the client" do
27
+ request.open_timeout = 30
28
+ request.read_timeout = 40
81
29
 
82
- request = HTTPI::Request.new(@server.url + 'ntlm-auth')
83
- request.auth.ntlm("testing", "failures")
30
+ adapter.client.expects(:open_timeout=).with(30)
31
+ adapter.client.expects(:read_timeout=).with(40)
84
32
 
85
- expect { HTTPI.get(request, adapter) }.
86
- to raise_error(HTTPI::NotSupportedError, /Net::NTLM is not available/)
87
- end
88
- end
89
-
90
- # it does not support digest auth
91
-
92
- if RUBY_PLATFORM =~ /java/
93
- pending "Puma Server complains: SSL not supported on JRuby"
94
- else
95
- context "https requests" do
96
- before :all do
97
- @server = IntegrationServer.run(:ssl => true)
33
+ adapter.request(:get)
34
+ end
98
35
  end
99
- after :all do
100
- @server.stop
101
- end
102
-
103
- # it does not raise when no certificate was set up
104
- it "works when set up properly" do
105
- request = HTTPI::Request.new(@server.url)
106
- request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
107
36
 
108
- response = HTTPI.get(request, adapter)
109
- expect(response.body).to eq("get")
37
+ describe "write_timeout" do
38
+ if Net::HTTP.method_defined?(:write_timeout=)
39
+ it "is being set on the client" do
40
+ request.write_timeout = 50
41
+ adapter.client.expects(:write_timeout=).with(50)
42
+ adapter.request(:get)
43
+ end
44
+ else
45
+ it "can not be set on the client" do
46
+ request.write_timeout = 50
47
+ expect { adapter.request(:get) }
48
+ .to raise_error(HTTPI::NotSupportedError, /write_timeout/)
49
+ end
50
+ end
110
51
  end
111
52
  end
112
53
  end
113
-
114
54
  end
@@ -82,14 +82,12 @@ describe HTTPI::Adapter::NetHTTP do
82
82
  end
83
83
  end
84
84
 
85
- describe "set_auth" do
86
- before do
87
- request.auth.basic "username", "password"
88
- end
89
-
90
- it "is not supported" do
91
- expect { client.request(:get) }.
92
- to raise_error(HTTPI::NotSupportedError, "Rack adapter does not support HTTP auth")
85
+ describe "basic auth" do
86
+ it "is supported" do
87
+ request = HTTPI::Request.new(@url + "basic-auth")
88
+ request.auth.basic("admin", "secret")
89
+ response = HTTPI.get(request, adapter)
90
+ expect(response.body).to eq("basic-auth")
93
91
  end
94
92
  end
95
93
 
@@ -3,7 +3,8 @@ require "httpi/auth/ssl"
3
3
 
4
4
  describe HTTPI::Auth::SSL do
5
5
  before(:all) do
6
- @ssl_versions = OpenSSL::SSL::SSLContext::METHODS.reject { |method| method.match /server|client/ }.sort.reverse
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"
@@ -6,11 +6,9 @@ require "excon"
6
6
  require "net/http/persistent"
7
7
  require "http"
8
8
 
9
- unless RUBY_VERSION < "1.9"
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
 
@@ -269,6 +267,20 @@ describe HTTPI do
269
267
 
270
268
  client.request(:custom, request, :httpclient)
271
269
  end
270
+
271
+ it 'follows redirects at maximum of the redirect limit' do
272
+ request.follow_redirect = true
273
+ request.redirect_limit = 2
274
+ redirect_location = 'http://foo.bar'
275
+
276
+ redirect = HTTPI::Response.new(302, {'location' => redirect_location}, 'Moved')
277
+ response = HTTPI::Response.new(200, {}, 'success')
278
+
279
+ httpclient.any_instance.expects(:request).times(2).with(:custom).returns(redirect, response)
280
+ request.expects(:url=).with(URI.parse(redirect_location))
281
+
282
+ client.request(:custom, request, :httpclient)
283
+ end
272
284
  end
273
285
 
274
286
  HTTPI::REQUEST_METHODS.each do |method|
@@ -280,7 +292,7 @@ describe HTTPI do
280
292
  end
281
293
 
282
294
  HTTPI::Adapter::ADAPTERS.each do |adapter, opts|
283
- unless (adapter == :em_http && RUBY_VERSION =~ /1\.8/) || (adapter == :curb && RUBY_PLATFORM =~ /java/)
295
+ unless (adapter == :em_http || adapter == :curb) && RUBY_PLATFORM =~ /java/
284
296
  client_class = {
285
297
  :httpclient => lambda { HTTPClient },
286
298
  :curb => lambda { Curl::Easy },
@@ -108,6 +108,11 @@ describe HTTPI::Request do
108
108
  expect(request.proxy).to eq(URI("http://proxy.example.com"))
109
109
  end
110
110
 
111
+ it 'also accepts the socks URL to use as a String' do
112
+ request.proxy ="socks://socks.example.com"
113
+ expect(request.proxy).to eq(URI("socks://socks.example.com"))
114
+ end
115
+
111
116
  it "also accepts a URI object" do
112
117
  request.proxy = URI("http://proxy.example.com")
113
118
  expect(request.proxy).to eq(URI("http://proxy.example.com"))
@@ -33,6 +33,17 @@ describe HTTPI::Adapter::Curb do
33
33
  expect(response.headers["Set-Cookie"]).to eq(cookies)
34
34
  end
35
35
 
36
+ it "it supports read timeout" do
37
+ require "curb"
38
+
39
+ request = HTTPI::Request.new(@server.url + "timeout")
40
+ request.read_timeout = 0.5 # seconds
41
+
42
+ expect do
43
+ HTTPI.get(request, adapter)
44
+ end.to raise_exception(Curl::Err::TimeoutError)
45
+ end
46
+
36
47
  it "executes GET requests" do
37
48
  response = HTTPI.get(@server.url, adapter)
38
49
  expect(response.body).to eq("get")
@@ -112,6 +123,15 @@ describe HTTPI::Adapter::Curb do
112
123
  response = HTTPI.get(request, adapter)
113
124
  expect(response.body).to eq("get")
114
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
115
135
  end
116
136
 
117
137
  end