httpi 2.4.0 → 2.4.5

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 (42) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +3 -5
  3. data/CHANGELOG.md +42 -0
  4. data/Gemfile +5 -1
  5. data/README.md +7 -7
  6. data/Rakefile +5 -3
  7. data/httpi.gemspec +2 -1
  8. data/lib/httpi.rb +5 -4
  9. data/lib/httpi/adapter.rb +1 -1
  10. data/lib/httpi/adapter/curb.rb +18 -5
  11. data/lib/httpi/adapter/em_http.rb +5 -4
  12. data/lib/httpi/adapter/excon.rb +16 -5
  13. data/lib/httpi/adapter/http.rb +88 -0
  14. data/lib/httpi/adapter/httpclient.rb +15 -4
  15. data/lib/httpi/adapter/net_http.rb +43 -16
  16. data/lib/httpi/adapter/net_http_persistent.rb +10 -1
  17. data/lib/httpi/adapter/rack.rb +13 -6
  18. data/lib/httpi/auth/ssl.rb +49 -2
  19. data/lib/httpi/logger.rb +6 -1
  20. data/lib/httpi/request.rb +12 -5
  21. data/lib/httpi/response.rb +2 -0
  22. data/lib/httpi/version.rb +1 -1
  23. data/spec/httpi/adapter/curb_spec.rb +56 -18
  24. data/spec/httpi/adapter/em_http_spec.rb +21 -13
  25. data/spec/httpi/adapter/excon_spec.rb +28 -90
  26. data/spec/httpi/adapter/http_spec.rb +28 -0
  27. data/spec/httpi/adapter/httpclient_spec.rb +39 -4
  28. data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
  29. data/spec/httpi/adapter/net_http_spec.rb +39 -99
  30. data/spec/httpi/adapter/rack_spec.rb +6 -8
  31. data/spec/httpi/auth/ssl_spec.rb +32 -1
  32. data/spec/httpi/httpi_spec.rb +17 -1
  33. data/spec/httpi/request_spec.rb +5 -0
  34. data/spec/integration/curb_spec.rb +11 -0
  35. data/spec/integration/em_http_spec.rb +17 -0
  36. data/spec/integration/excon_spec.rb +165 -0
  37. data/spec/integration/http_spec.rb +147 -0
  38. data/spec/integration/httpclient_spec.rb +11 -0
  39. data/spec/integration/net_http_persistent_spec.rb +22 -1
  40. data/spec/integration/net_http_spec.rb +127 -1
  41. data/spec/integration/support/application.rb +4 -2
  42. metadata +35 -4
@@ -89,15 +89,12 @@ begin
89
89
  end
90
90
 
91
91
  it "sets host, port and authorization" do
92
- url = 'http://example.com:80'
93
-
92
+ url = "http://example.com:80"
94
93
  connection_options = {
95
- :connect_timeout => nil,
96
- :inactivity_timeout => nil,
97
- :proxy => {
98
- :host => 'proxy-host.com',
99
- :port => 443,
100
- :authorization => ['username', 'password']
94
+ :proxy => {
95
+ :host => "proxy-host.com",
96
+ :port => 443,
97
+ :authorization => ["username", "password"]
101
98
  }
102
99
  }
103
100
 
@@ -111,8 +108,8 @@ begin
111
108
  it "is passed as a connection option" do
112
109
  request.open_timeout = 30
113
110
 
114
- url = 'http://example.com:80'
115
- connection_options = { :connect_timeout => 30, :inactivity_timeout => nil }
111
+ url = "http://example.com:80"
112
+ connection_options = { connect_timeout: 30 }
116
113
 
117
114
  EventMachine::HttpRequest.expects(:new).with(url, connection_options)
118
115
 
@@ -121,11 +118,22 @@ begin
121
118
  end
122
119
 
123
120
  describe "receive_timeout" do
124
- it "is passed as a connection option" do
121
+ it "is passed as a connection option (when read_timeout specified)" do
125
122
  request.read_timeout = 60
126
123
 
127
- url = 'http://example.com:80'
128
- connection_options = { :connect_timeout => nil, :inactivity_timeout => 60 }
124
+ url = "http://example.com:80"
125
+ connection_options = { inactivity_timeout: 60 }
126
+
127
+ EventMachine::HttpRequest.expects(:new).with(url, connection_options)
128
+
129
+ adapter
130
+ end
131
+
132
+ it "is passed as a connection option (when write_timeout specified)" do
133
+ request.write_timeout = 60
134
+
135
+ url = "http://example.com:80"
136
+ connection_options = { inactivity_timeout: 60 }
129
137
 
130
138
  EventMachine::HttpRequest.expects(:new).with(url, connection_options)
131
139
 
@@ -1,96 +1,34 @@
1
1
  require "spec_helper"
2
- require "integration/support/server"
3
-
4
- describe HTTPI::Adapter::Excon do
5
-
6
- subject(:adapter) { :excon }
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 ntlm authentication" do
64
- request = HTTPI::Request.new(@server.url + "ntlm-auth")
65
- request.auth.ntlm("tester", "vReqSoafRe5O")
66
-
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
73
-
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)
2
+ require "httpi/adapter/excon"
3
+ require "httpi/request"
4
+
5
+ begin
6
+ HTTPI::Adapter.load_adapter(:excon)
7
+
8
+ describe HTTPI::Adapter::Excon do
9
+ let(:adapter) { HTTPI::Adapter::Excon.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 passed as connection options" do
15
+ request.open_timeout = 30
16
+ request.read_timeout = 40
17
+ request.write_timeout = 50
18
+
19
+ expect(adapter.client.data).to include(
20
+ connect_timeout: 30,
21
+ read_timeout: 40,
22
+ write_timeout: 50
23
+ )
24
+ end
80
25
  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
-
90
- response = HTTPI.get(request, adapter)
91
- expect(response.body).to eq("get")
26
+ describe "host, hostname" do
27
+ it "both are set" do
28
+ Excon.expects(:display_warning).never
29
+ expect(adapter.client.data).to include(host: 'example.com', hostname: 'example.com')
30
+ end
92
31
  end
93
32
  end
94
33
  end
95
-
96
34
  end
@@ -0,0 +1,28 @@
1
+ require "spec_helper"
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
25
+ end
26
+ end
27
+ end
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"
@@ -155,6 +178,17 @@ describe HTTPI::Adapter::HTTPClient do
155
178
 
156
179
  adapter.request(:get)
157
180
  end
181
+
182
+ it 'raises error when min_version not nil' do
183
+ request.auth.ssl.min_version = :TLS1_2
184
+ expect{ adapter.request(:get) }.
185
+ to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
186
+ end
187
+ it 'raises error when max_version not nil' do
188
+ request.auth.ssl.max_version = :TLS1_2
189
+ expect{ adapter.request(:get) }.
190
+ to raise_error(HTTPI::NotSupportedError, 'Httpclient adapter does not support #min_version or #max_version. Please, use #ssl_version instead')
191
+ end
158
192
  end
159
193
 
160
194
  context "(for SSL client auth with a verify mode of :none with no certs provided)" do
@@ -174,11 +208,12 @@ describe HTTPI::Adapter::HTTPClient do
174
208
  end
175
209
  end
176
210
 
177
- it "does not support NTLM authentication" do
178
- request.auth.ntlm("tester", "vReqSoafRe5O")
211
+ it "supports NTLM authentication" do
212
+ request = HTTPI::Request.new(@server.url + "ntlm-auth")
179
213
 
180
- expect { adapter.request(:get) }.
181
- to raise_error(HTTPI::NotSupportedError, /adapter does not support NTLM authentication/)
214
+ request.auth.ntlm("tester", "vReqSoafRe5O")
215
+ response = HTTPI.get(request, :httpclient)
216
+ expect(response.body).to eq("ntlm-auth")
182
217
  end
183
218
 
184
219
  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