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
@@ -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