httpi 2.4.3 → 2.4.4
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/README.md +3 -3
- data/lib/httpi/adapter/curb.rb +3 -2
- data/lib/httpi/adapter/em_http.rb +5 -4
- data/lib/httpi/adapter/excon.rb +2 -1
- data/lib/httpi/adapter/http.rb +6 -0
- data/lib/httpi/adapter/httpclient.rb +1 -0
- data/lib/httpi/adapter/net_http.rb +7 -0
- data/lib/httpi/adapter/net_http_persistent.rb +1 -0
- data/lib/httpi/auth/ssl.rb +1 -1
- data/lib/httpi/request.rb +2 -2
- data/lib/httpi/version.rb +1 -1
- data/spec/httpi/adapter/curb_spec.rb +14 -7
- data/spec/httpi/adapter/em_http_spec.rb +21 -13
- data/spec/httpi/adapter/excon_spec.rb +23 -119
- data/spec/httpi/adapter/http_spec.rb +23 -96
- data/spec/httpi/adapter/httpclient_spec.rb +14 -0
- data/spec/httpi/adapter/net_http_persistent_spec.rb +31 -81
- data/spec/httpi/adapter/net_http_spec.rb +37 -181
- data/spec/integration/curb_spec.rb +11 -0
- data/spec/integration/em_http_spec.rb +17 -0
- data/spec/integration/excon_spec.rb +47 -0
- data/spec/integration/http_spec.rb +28 -0
- data/spec/integration/httpclient_spec.rb +11 -0
- data/spec/integration/net_http_persistent_spec.rb +21 -2
- data/spec/integration/net_http_spec.rb +117 -1
- data/spec/integration/support/application.rb +3 -2
- metadata +3 -3
@@ -100,6 +100,20 @@ describe HTTPI::Adapter::HTTPClient do
|
|
100
100
|
end
|
101
101
|
end
|
102
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
|
+
|
103
117
|
describe "set_auth" do
|
104
118
|
it "is set for HTTP basic auth" do
|
105
119
|
request.auth.basic "username", "password"
|
@@ -1,96 +1,46 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require "
|
2
|
+
require "httpi/adapter/net_http_persistent"
|
3
|
+
require "httpi/request"
|
3
4
|
|
4
|
-
|
5
|
+
begin
|
6
|
+
HTTPI::Adapter.load_adapter(:net_http_persistent)
|
5
7
|
|
6
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
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
|
-
|
60
|
-
|
20
|
+
before do
|
21
|
+
Net::HTTP::Persistent.any_instance.stubs(:start).returns(response)
|
61
22
|
end
|
62
23
|
|
63
|
-
|
64
|
-
|
65
|
-
|
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
|
-
|
68
|
-
|
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
|
-
|
75
|
-
|
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
|
-
|
91
|
-
|
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,198 +1,54 @@
|
|
1
1
|
require "spec_helper"
|
2
|
-
require "
|
2
|
+
require "httpi/adapter/net_http"
|
3
|
+
require "httpi/request"
|
3
4
|
|
4
|
-
|
5
|
+
begin
|
6
|
+
HTTPI::Adapter.load_adapter(:net_http)
|
5
7
|
|
6
|
-
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
after :all do
|
14
|
-
@server.stop
|
15
|
-
end
|
16
|
-
|
17
|
-
context 'when socks is specified' do
|
18
|
-
|
19
|
-
let(:socks_client) { mock('socks_client') }
|
20
|
-
let(:request){HTTPI::Request.new(@server.url)}
|
21
|
-
|
22
|
-
it 'uses Net::HTTP.SOCKSProxy as client' do
|
23
|
-
socks_client.expects(:new).with(URI(@server.url).host, URI(@server.url).port).returns(:socks_client_instance)
|
24
|
-
Net::HTTP.expects(:SOCKSProxy).with('localhost', 8080).returns socks_client
|
25
|
-
|
26
|
-
request.proxy = 'socks://localhost:8080'
|
27
|
-
adapter = HTTPI::Adapter::NetHTTP.new(request)
|
28
|
-
|
29
|
-
expect(adapter.client).to eq(:socks_client_instance)
|
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"})
|
30
17
|
end
|
31
|
-
|
32
|
-
|
33
|
-
it "sends and receives HTTP headers" do
|
34
|
-
request = HTTPI::Request.new(@server.url + "x-header")
|
35
|
-
request.headers["X-Header"] = "HTTPI"
|
36
|
-
|
37
|
-
response = HTTPI.get(request, adapter)
|
38
|
-
expect(response.body).to include("HTTPI")
|
39
|
-
end
|
18
|
+
}
|
40
19
|
|
41
|
-
|
42
|
-
|
43
|
-
expect(response.body).to eq("get")
|
44
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
20
|
+
before do
|
21
|
+
Net::HTTP.any_instance.stubs(:start).returns(response)
|
45
22
|
end
|
46
23
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
it "executes HEAD requests" do
|
54
|
-
response = HTTPI.head(@server.url, adapter)
|
55
|
-
expect(response.code).to eq(200)
|
56
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
57
|
-
end
|
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
|
58
29
|
|
59
|
-
|
60
|
-
|
61
|
-
expect(response.body).to eq("put")
|
62
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
63
|
-
end
|
30
|
+
adapter.client.expects(:open_timeout=).with(30)
|
31
|
+
adapter.client.expects(:read_timeout=).with(40)
|
64
32
|
|
65
|
-
|
66
|
-
response = HTTPI.delete(@server.url, adapter)
|
67
|
-
expect(response.body).to eq("delete")
|
68
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
69
|
-
end
|
70
|
-
|
71
|
-
context "supports custom methods supported by Net::HTTP" do
|
72
|
-
let(:request) do
|
73
|
-
HTTPI::Request.new(@server.url).tap do|r|
|
74
|
-
r.body = request_body if request_body
|
33
|
+
adapter.request(:get)
|
75
34
|
end
|
76
35
|
end
|
77
36
|
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
end
|
93
|
-
|
94
|
-
context 'UNSUPPORTED method' do
|
95
|
-
let(:http_method) { :unsupported }
|
96
|
-
|
97
|
-
specify { expect { response }.to raise_error HTTPI::NotSupportedError }
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
it "supports basic authentication" do
|
102
|
-
request = HTTPI::Request.new(@server.url + "basic-auth")
|
103
|
-
request.auth.basic("admin", "secret")
|
104
|
-
|
105
|
-
response = HTTPI.get(request, adapter)
|
106
|
-
expect(response.body).to eq("basic-auth")
|
107
|
-
end
|
108
|
-
|
109
|
-
it "does not support digest authentication" do
|
110
|
-
request = HTTPI::Request.new(@server.url + "digest-auth")
|
111
|
-
request.auth.digest("admin", "secret")
|
112
|
-
|
113
|
-
expect { HTTPI.get(request, adapter) }.
|
114
|
-
to raise_error(HTTPI::NotSupportedError, /does not support HTTP digest authentication/)
|
115
|
-
end
|
116
|
-
|
117
|
-
it "supports ntlm authentication" do
|
118
|
-
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
119
|
-
request.auth.ntlm("tester", "vReqSoafRe5O")
|
120
|
-
|
121
|
-
response = HTTPI.get(request, adapter)
|
122
|
-
expect(response.body).to eq("ntlm-auth")
|
123
|
-
end
|
124
|
-
|
125
|
-
it 'does not support ntlm authentication when Net::NTLM is not available' do
|
126
|
-
Net.expects(:const_defined?).with(:NTLM).returns false
|
127
|
-
|
128
|
-
request = HTTPI::Request.new(@server.url + 'ntlm-auth')
|
129
|
-
request.auth.ntlm("testing", "failures")
|
130
|
-
|
131
|
-
expect { HTTPI.get(request, adapter) }.
|
132
|
-
to raise_error(HTTPI::NotSupportedError, /Net::NTLM is not available/)
|
133
|
-
end
|
134
|
-
|
135
|
-
it 'does not require ntlm when ntlm authenication is not requested' do
|
136
|
-
HTTPI::Adapter::NetHTTP.any_instance.stubs(:check_net_ntlm_version!).raises(RuntimeError)
|
137
|
-
request = HTTPI::Request.new(@server.url)
|
138
|
-
expect(request.auth.ntlm?).to be false
|
139
|
-
|
140
|
-
# make sure a request doesn't call ntlm check if we don't ask for it.
|
141
|
-
expect { HTTPI.get(request, adapter) }.not_to raise_error
|
142
|
-
HTTPI::Adapter::NetHTTP.any_instance.unstub(:check_net_ntlm_version!)
|
143
|
-
end
|
144
|
-
|
145
|
-
it 'does check ntlm when ntlm authentication is requested' do
|
146
|
-
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
147
|
-
request.auth.ntlm("tester", "vReqSoafRe5O")
|
148
|
-
|
149
|
-
expect { HTTPI.get(request, adapter) }.not_to raise_error
|
150
|
-
|
151
|
-
# the check should also verify that the version of ntlm is supported and still fail if it isn't
|
152
|
-
HTTPI::Adapter::NetHTTP.any_instance.stubs(:ntlm_version).returns("0.1.1")
|
153
|
-
|
154
|
-
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
155
|
-
request.auth.ntlm("tester", "vReqSoafRe5O")
|
156
|
-
|
157
|
-
expect { HTTPI.get(request, adapter) }.to raise_error(ArgumentError, /Invalid version/)
|
158
|
-
|
159
|
-
HTTPI::Adapter::NetHTTP.any_instance.unstub(:ntlm_version)
|
160
|
-
end
|
161
|
-
|
162
|
-
it "does not crash when authenticate header is missing (on second request)" do
|
163
|
-
request = HTTPI::Request.new(@server.url + 'ntlm-auth')
|
164
|
-
request.auth.ntlm("tester", "vReqSoafRe5O")
|
165
|
-
|
166
|
-
expect { HTTPI.get(request, adapter) }.
|
167
|
-
to_not raise_error
|
168
|
-
|
169
|
-
expect { HTTPI.get(request, adapter) }.
|
170
|
-
to_not raise_error
|
171
|
-
end
|
172
|
-
end
|
173
|
-
|
174
|
-
# it does not support digest auth
|
175
|
-
|
176
|
-
if RUBY_PLATFORM =~ /java/
|
177
|
-
pending "Puma Server complains: SSL not supported on JRuby"
|
178
|
-
else
|
179
|
-
context "https requests" do
|
180
|
-
before :all do
|
181
|
-
@server = IntegrationServer.run(:ssl => true)
|
182
|
-
end
|
183
|
-
after :all do
|
184
|
-
@server.stop
|
185
|
-
end
|
186
|
-
|
187
|
-
# it does not raise when no certificate was set up
|
188
|
-
it "works when set up properly" do
|
189
|
-
request = HTTPI::Request.new(@server.url)
|
190
|
-
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
191
|
-
|
192
|
-
response = HTTPI.get(request, adapter)
|
193
|
-
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
|
194
51
|
end
|
195
52
|
end
|
196
53
|
end
|
197
|
-
|
198
54
|
end
|
@@ -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")
|
@@ -42,6 +42,23 @@ describe HTTPI::Adapter::EmHttpRequest do
|
|
42
42
|
expect(response.headers["Set-Cookie"]).to eq(cookies)
|
43
43
|
end
|
44
44
|
|
45
|
+
if RUBY_PLATFORM =~ /java/
|
46
|
+
pending <<-MSG
|
47
|
+
It seems like JRuby is missing support for inactivity timeout! See related issues on GitHub:
|
48
|
+
- https://github.com/eventmachine/eventmachine/issues/155
|
49
|
+
- https://github.com/eventmachine/eventmachine/pull/312
|
50
|
+
MSG
|
51
|
+
else
|
52
|
+
it "it supports read timeout" do
|
53
|
+
request = HTTPI::Request.new(@server.url + "timeout")
|
54
|
+
request.read_timeout = 0.5 # seconds
|
55
|
+
|
56
|
+
expect do
|
57
|
+
HTTPI.get(request, adapter)
|
58
|
+
end.to raise_exception(HTTPI::TimeoutError)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
45
62
|
it "executes GET requests" do
|
46
63
|
response = HTTPI.get(@server.url, adapter)
|
47
64
|
expect(response.body).to eq("get")
|
@@ -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 "excon"
|
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(Excon::Error::Timeout)
|
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")
|
@@ -68,6 +79,21 @@ describe HTTPI::Adapter::HTTPClient do
|
|
68
79
|
expect(response.body).to eq("basic-auth")
|
69
80
|
end
|
70
81
|
|
82
|
+
it "does not support ntlm authentication" do
|
83
|
+
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
84
|
+
request.auth.ntlm("tester", "vReqSoafRe5O")
|
85
|
+
|
86
|
+
expect { HTTPI.get(request, adapter) }.
|
87
|
+
to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
|
88
|
+
end
|
89
|
+
|
90
|
+
it "supports disabling verify mode" do
|
91
|
+
request = HTTPI::Request.new(@server.url)
|
92
|
+
request.auth.ssl.verify_mode = :none
|
93
|
+
adapter_class = HTTPI::Adapter.load(adapter).new(request)
|
94
|
+
expect(adapter_class.client.data[:ssl_verify_peer]).to eq(false)
|
95
|
+
end
|
96
|
+
|
71
97
|
it "supports chunked response" do
|
72
98
|
request = HTTPI::Request.new(@server.url)
|
73
99
|
res = ""
|
@@ -102,6 +128,27 @@ describe HTTPI::Adapter::HTTPClient do
|
|
102
128
|
response = HTTPI.get(request, adapter)
|
103
129
|
expect(response.body).to eq("get")
|
104
130
|
end
|
131
|
+
|
132
|
+
it "works with client cert and key provided as file path" do
|
133
|
+
request = HTTPI::Request.new(@server.url)
|
134
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
135
|
+
request.auth.ssl.cert_file = "spec/fixtures/client_cert.pem"
|
136
|
+
request.auth.ssl.cert_key_file = "spec/fixtures/client_key.pem"
|
137
|
+
|
138
|
+
response = HTTPI.get(request, adapter)
|
139
|
+
expect(response.body).to eq("get")
|
140
|
+
end
|
141
|
+
|
142
|
+
it "works with client cert and key set directly" do
|
143
|
+
request = HTTPI::Request.new(@server.url)
|
144
|
+
|
145
|
+
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
146
|
+
request.auth.ssl.cert = OpenSSL::X509::Certificate.new File.open("spec/fixtures/client_cert.pem").read
|
147
|
+
request.auth.ssl.cert_key = OpenSSL::PKey.read File.open("spec/fixtures/client_key.pem").read
|
148
|
+
|
149
|
+
response = HTTPI.get(request, adapter)
|
150
|
+
expect(response.body).to eq("get")
|
151
|
+
end
|
105
152
|
end
|
106
153
|
end
|
107
154
|
|