httpi 4.0.3 → 4.0.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 +4 -0
- data/lib/httpi/version.rb +1 -1
- metadata +2 -50
- data/.devcontainer/devcontainer.json +0 -22
- data/.github/workflows/development.yml +0 -49
- data/.gitignore +0 -11
- data/.rspec +0 -1
- data/Gemfile +0 -22
- data/Rakefile +0 -18
- data/httpi.gemspec +0 -40
- data/spec/fixtures/attachment.gif +0 -0
- data/spec/fixtures/client_cert.pem +0 -20
- data/spec/fixtures/client_key.pem +0 -27
- data/spec/fixtures/xml.gz +0 -0
- data/spec/fixtures/xml.xml +0 -10
- data/spec/fixtures/xml_dime.dime +0 -0
- data/spec/fixtures/xml_dime.xml +0 -1
- data/spec/httpi/adapter/base_spec.rb +0 -23
- data/spec/httpi/adapter/curb_spec.rb +0 -351
- data/spec/httpi/adapter/em_http_spec.rb +0 -180
- data/spec/httpi/adapter/excon_spec.rb +0 -34
- data/spec/httpi/adapter/http_spec.rb +0 -28
- data/spec/httpi/adapter/httpclient_spec.rb +0 -238
- data/spec/httpi/adapter/net_http_persistent_spec.rb +0 -46
- data/spec/httpi/adapter/net_http_spec.rb +0 -54
- data/spec/httpi/adapter/rack_spec.rb +0 -109
- data/spec/httpi/adapter_spec.rb +0 -68
- data/spec/httpi/auth/config_spec.rb +0 -163
- data/spec/httpi/auth/ssl_spec.rb +0 -216
- data/spec/httpi/cookie_spec.rb +0 -36
- data/spec/httpi/cookie_store_spec.rb +0 -26
- data/spec/httpi/error_spec.rb +0 -43
- data/spec/httpi/httpi_spec.rb +0 -382
- data/spec/httpi/request_spec.rb +0 -290
- data/spec/httpi/response_spec.rb +0 -146
- data/spec/integration/curb_spec.rb +0 -140
- data/spec/integration/em_http_spec.rb +0 -108
- data/spec/integration/excon_spec.rb +0 -174
- data/spec/integration/fixtures/ca_all.pem +0 -19
- data/spec/integration/fixtures/server.cert +0 -19
- data/spec/integration/fixtures/server.key +0 -27
- data/spec/integration/http_spec.rb +0 -156
- data/spec/integration/httpclient_spec.rb +0 -137
- data/spec/integration/net_http_persistent_spec.rb +0 -171
- data/spec/integration/net_http_spec.rb +0 -282
- data/spec/integration/support/application.rb +0 -88
- data/spec/integration/support/server.rb +0 -83
- data/spec/spec_helper.rb +0 -23
- data/spec/support/error_helper.rb +0 -26
- data/spec/support/fixture.rb +0 -27
- data/spec/support/matchers.rb +0 -19
@@ -1,171 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "integration/support/server"
|
3
|
-
require "net/http/persistent"
|
4
|
-
|
5
|
-
describe HTTPI::Adapter::NetHTTPPersistent do
|
6
|
-
|
7
|
-
subject(:adapter) { :net_http_persistent }
|
8
|
-
|
9
|
-
context "http requests" do
|
10
|
-
before :all do
|
11
|
-
@server = IntegrationServer.run
|
12
|
-
end
|
13
|
-
|
14
|
-
after :all do
|
15
|
-
@server.stop
|
16
|
-
end
|
17
|
-
|
18
|
-
it "sends and receives HTTP headers" do
|
19
|
-
request = HTTPI::Request.new(@server.url + "x-header")
|
20
|
-
request.headers["X-Header"] = "HTTPI"
|
21
|
-
|
22
|
-
response = HTTPI.get(request, adapter)
|
23
|
-
expect(response.body).to include("HTTPI")
|
24
|
-
end
|
25
|
-
|
26
|
-
it "it supports headers with multiple values" do
|
27
|
-
request = HTTPI::Request.new(@server.url + "cookies")
|
28
|
-
|
29
|
-
response = HTTPI.get(request, adapter)
|
30
|
-
cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
|
31
|
-
expect(response.headers["Set-Cookie"]).to eq(cookies)
|
32
|
-
end
|
33
|
-
|
34
|
-
it "it supports read timeout" do
|
35
|
-
require "net/http/persistent"
|
36
|
-
|
37
|
-
request = HTTPI::Request.new(@server.url + "timeout")
|
38
|
-
request.read_timeout = 0.5 # seconds
|
39
|
-
|
40
|
-
expect do
|
41
|
-
HTTPI.get(request, adapter)
|
42
|
-
end.to raise_exception(Net::ReadTimeout)
|
43
|
-
end
|
44
|
-
|
45
|
-
it "executes GET requests" do
|
46
|
-
response = HTTPI.get(@server.url, adapter)
|
47
|
-
expect(response.body).to eq("get")
|
48
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
49
|
-
end
|
50
|
-
|
51
|
-
it "executes POST requests" do
|
52
|
-
request = HTTPI::Request.new(url: @server.url, body: "<some>xml</some>")
|
53
|
-
|
54
|
-
response = HTTPI.post(request, adapter)
|
55
|
-
expect(response.body).to eq("post")
|
56
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
57
|
-
end
|
58
|
-
|
59
|
-
it "executes HEAD requests" do
|
60
|
-
response = HTTPI.head(@server.url, adapter)
|
61
|
-
expect(response.code).to eq(200)
|
62
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
63
|
-
end
|
64
|
-
|
65
|
-
it "executes PUT requests" do
|
66
|
-
response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
|
67
|
-
expect(response.body).to eq("put")
|
68
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
69
|
-
end
|
70
|
-
|
71
|
-
it "executes DELETE requests" do
|
72
|
-
response = HTTPI.delete(@server.url, adapter)
|
73
|
-
expect(response.body).to eq("delete")
|
74
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
75
|
-
end
|
76
|
-
|
77
|
-
it "supports basic authentication" do
|
78
|
-
request = HTTPI::Request.new(@server.url + "basic-auth")
|
79
|
-
request.auth.basic("admin", "secret")
|
80
|
-
|
81
|
-
response = HTTPI.get(request, adapter)
|
82
|
-
expect(response.body).to eq("basic-auth")
|
83
|
-
end
|
84
|
-
|
85
|
-
it "does not support ntlm authentication" do
|
86
|
-
request = HTTPI::Request.new(@server.url + "ntlm-auth")
|
87
|
-
request.auth.ntlm("tester", "vReqSoafRe5O")
|
88
|
-
|
89
|
-
expect { HTTPI.get(request, adapter) }.
|
90
|
-
to raise_error(HTTPI::NotSupportedError, /does not support NTLM authentication/)
|
91
|
-
end
|
92
|
-
|
93
|
-
# it does not support digest authentication
|
94
|
-
|
95
|
-
it "supports chunked response" do
|
96
|
-
request = HTTPI::Request.new(@server.url)
|
97
|
-
res = ""
|
98
|
-
request.on_body do |body|
|
99
|
-
res += body
|
100
|
-
end
|
101
|
-
response = HTTPI.post(request, adapter)
|
102
|
-
expect(res).to eq("post")
|
103
|
-
expect(response.body.to_s).to eq("")
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
if RUBY_PLATFORM =~ /java/
|
108
|
-
pending "Puma Server complains: SSL not supported on JRuby"
|
109
|
-
else
|
110
|
-
context "https requests" do
|
111
|
-
before :all do
|
112
|
-
@server = IntegrationServer.run(:ssl => true)
|
113
|
-
end
|
114
|
-
|
115
|
-
after :all do
|
116
|
-
@server.stop
|
117
|
-
end
|
118
|
-
|
119
|
-
# does not raise when no certificate was set up
|
120
|
-
it "works when set up properly" do
|
121
|
-
request = HTTPI::Request.new(@server.url)
|
122
|
-
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
123
|
-
|
124
|
-
response = HTTPI.get(request, adapter)
|
125
|
-
expect(response.body).to eq("get")
|
126
|
-
end
|
127
|
-
|
128
|
-
it "works with ciphers" do
|
129
|
-
request = HTTPI::Request.new(@server.url)
|
130
|
-
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
131
|
-
request.auth.ssl.ciphers = OpenSSL::SSL::SSLContext.new.ciphers
|
132
|
-
|
133
|
-
response = HTTPI.get(request, adapter)
|
134
|
-
expect(response.body).to eq("get")
|
135
|
-
end
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
# The built-in Rack IntegrationServer and specs support a basic simulated NTLM exchange
|
140
|
-
# that does not require anything outside of the normal gem test infrastructure.
|
141
|
-
# (see spec/httpi/adapter/net_http_spec.rb: it "supports ntlm authentication"
|
142
|
-
# and spec/integration/support/application.rb: map "/ntlm-auth")
|
143
|
-
# But since that simulated exchange is based on recorded traffic, you may wish to
|
144
|
-
# run the following integration test against a real external NTLM server from time to time.
|
145
|
-
#
|
146
|
-
# This test must be specially enabled because it requires an external
|
147
|
-
# Windows 2012 Server configured according to the instructions found here:
|
148
|
-
# https://github.com/savonrb/httpi/wiki/NTLM-Integration-Test-Plan
|
149
|
-
#
|
150
|
-
# Once you have that server running as instructed, you can include this test by setting
|
151
|
-
# NTLM=external via the command line, e.g.:
|
152
|
-
# $ NTLM=external bundle exec rspec
|
153
|
-
#
|
154
|
-
if ENV["NTLM"]=="external"
|
155
|
-
context "http request via NTLM" do
|
156
|
-
it "works with NTLM connections" do
|
157
|
-
user = "tester"
|
158
|
-
pass = "vReqSoafRe5O"
|
159
|
-
request = HTTPI::Request.new("http://ntlmtest/")
|
160
|
-
request.auth.ntlm(user,pass)
|
161
|
-
response = HTTPI.get(request, adapter)
|
162
|
-
expect(response.code).to eq(200)
|
163
|
-
expect(response.body).to match(/iis-8\.png/)
|
164
|
-
|
165
|
-
puts "EXTERNAL NTLM INTEGRATION TEST, response body:"
|
166
|
-
puts response.body
|
167
|
-
end
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
end
|
@@ -1,282 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
require "integration/support/server"
|
3
|
-
|
4
|
-
describe HTTPI::Adapter::NetHTTP do
|
5
|
-
|
6
|
-
subject(:adapter) { :net_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
|
-
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
|
-
|
32
|
-
it "sends and receives HTTP headers" do
|
33
|
-
request = HTTPI::Request.new(@server.url + "x-header")
|
34
|
-
request.headers["X-Header"] = "HTTPI"
|
35
|
-
|
36
|
-
response = HTTPI.get(request, adapter)
|
37
|
-
expect(response.body).to include("HTTPI")
|
38
|
-
end
|
39
|
-
|
40
|
-
it "it supports headers with multiple values" do
|
41
|
-
request = HTTPI::Request.new(@server.url + "cookies")
|
42
|
-
|
43
|
-
response = HTTPI.get(request, adapter)
|
44
|
-
cookies = ["cookie1=chip1; path=/", "cookie2=chip2; path=/"]
|
45
|
-
expect(response.headers["Set-Cookie"]).to eq(cookies)
|
46
|
-
end
|
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
|
-
|
59
|
-
it "executes GET requests" do
|
60
|
-
response = HTTPI.get(@server.url, adapter)
|
61
|
-
expect(response.body).to eq("get")
|
62
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
63
|
-
end
|
64
|
-
|
65
|
-
it "executes POST requests" do
|
66
|
-
response = HTTPI.post(@server.url, "<some>xml</some>", adapter)
|
67
|
-
expect(response.body).to eq("post")
|
68
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
69
|
-
end
|
70
|
-
|
71
|
-
it "executes HEAD requests" do
|
72
|
-
response = HTTPI.head(@server.url, adapter)
|
73
|
-
expect(response.code).to eq(200)
|
74
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
75
|
-
end
|
76
|
-
|
77
|
-
it "executes PUT requests" do
|
78
|
-
response = HTTPI.put(@server.url, "<some>xml</some>", adapter)
|
79
|
-
expect(response.body).to eq("put")
|
80
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
81
|
-
end
|
82
|
-
|
83
|
-
it "executes DELETE requests" do
|
84
|
-
response = HTTPI.delete(@server.url, adapter)
|
85
|
-
expect(response.body).to eq("delete")
|
86
|
-
expect(response.headers["Content-Type"]).to eq("text/plain")
|
87
|
-
end
|
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
|
-
|
125
|
-
it "supports basic authentication" do
|
126
|
-
request = HTTPI::Request.new(@server.url + "basic-auth")
|
127
|
-
request.auth.basic("admin", "secret")
|
128
|
-
|
129
|
-
response = HTTPI.get(request, adapter)
|
130
|
-
expect(response.body).to eq("basic-auth")
|
131
|
-
end
|
132
|
-
|
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
|
196
|
-
|
197
|
-
it "supports chunked response" do
|
198
|
-
request = HTTPI::Request.new(@server.url)
|
199
|
-
res = ""
|
200
|
-
request.on_body do |body|
|
201
|
-
res += body
|
202
|
-
end
|
203
|
-
response = HTTPI.post(request, adapter)
|
204
|
-
expect(res).to eq("post")
|
205
|
-
expect(response.body.to_s).to eq("")
|
206
|
-
end
|
207
|
-
end
|
208
|
-
|
209
|
-
if RUBY_PLATFORM =~ /java/
|
210
|
-
pending "Puma Server complains: SSL not supported on JRuby"
|
211
|
-
else
|
212
|
-
context "https requests" do
|
213
|
-
before :all do
|
214
|
-
@server = IntegrationServer.run(:ssl => true)
|
215
|
-
end
|
216
|
-
after :all do
|
217
|
-
@server.stop
|
218
|
-
end
|
219
|
-
|
220
|
-
# does not raise when no certificate was set up
|
221
|
-
it "works when set up properly" do
|
222
|
-
request = HTTPI::Request.new(@server.url)
|
223
|
-
request.auth.ssl.ca_cert_file = IntegrationServer.ssl_ca_file
|
224
|
-
|
225
|
-
response = HTTPI.get(request, adapter)
|
226
|
-
expect(response.body).to eq("get")
|
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
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
# The built-in Rack IntegrationServer and specs support a basic simulated NTLM exchange
|
251
|
-
# that does not require anything outside of the normal gem test infrastructure.
|
252
|
-
# (see spec/httpi/adapter/net_http_spec.rb: it "supports ntlm authentication"
|
253
|
-
# and spec/integration/support/application.rb: map "/ntlm-auth")
|
254
|
-
# But since that simulated exchange is based on recorded traffic, you may wish to
|
255
|
-
# run the following integration test against a real external NTLM server from time to time.
|
256
|
-
#
|
257
|
-
# This test must be specially enabled because it requires an external
|
258
|
-
# Windows 2012 Server configured according to the instructions found here:
|
259
|
-
# https://github.com/savonrb/httpi/wiki/NTLM-Integration-Test-Plan
|
260
|
-
#
|
261
|
-
# Once you have that server running as instructed, you can include this test by setting
|
262
|
-
# NTLM=external via the command line, e.g.:
|
263
|
-
# $ NTLM=external bundle exec rspec
|
264
|
-
#
|
265
|
-
if ENV["NTLM"]=="external"
|
266
|
-
context "http request via NTLM" do
|
267
|
-
it "works with NTLM connections" do
|
268
|
-
user = "tester"
|
269
|
-
pass = "vReqSoafRe5O"
|
270
|
-
request = HTTPI::Request.new("http://ntlmtest/")
|
271
|
-
request.auth.ntlm(user,pass)
|
272
|
-
response = HTTPI.get(request, adapter)
|
273
|
-
expect(response.code).to eq(200)
|
274
|
-
expect(response.body).to match(/iis-8\.png/)
|
275
|
-
|
276
|
-
puts "EXTERNAL NTLM INTEGRATION TEST, response body:"
|
277
|
-
puts response.body
|
278
|
-
end
|
279
|
-
end
|
280
|
-
end
|
281
|
-
|
282
|
-
end
|
@@ -1,88 +0,0 @@
|
|
1
|
-
require 'rack'
|
2
|
-
require "rack/builder"
|
3
|
-
|
4
|
-
class IntegrationServer
|
5
|
-
|
6
|
-
def self.respond_with(body)
|
7
|
-
[200, { "Content-Type" => "text/plain", "Content-Length" => body.size.to_s }, [body]]
|
8
|
-
end
|
9
|
-
|
10
|
-
Application = Rack::Builder.new do
|
11
|
-
|
12
|
-
map "/" do
|
13
|
-
run lambda { |env|
|
14
|
-
IntegrationServer.respond_with env["REQUEST_METHOD"].downcase
|
15
|
-
}
|
16
|
-
end
|
17
|
-
|
18
|
-
map "/timeout" do
|
19
|
-
run lambda { |env|
|
20
|
-
sleep 2
|
21
|
-
IntegrationServer.respond_with "done"
|
22
|
-
}
|
23
|
-
end
|
24
|
-
|
25
|
-
map "/x-header" do
|
26
|
-
run lambda { |env|
|
27
|
-
IntegrationServer.respond_with env["HTTP_X_HEADER"]
|
28
|
-
}
|
29
|
-
end
|
30
|
-
|
31
|
-
map "/cookies" do
|
32
|
-
run lambda { |env|
|
33
|
-
status, headers, body = IntegrationServer.respond_with("Many Cookies")
|
34
|
-
response = Rack::Response.new(body, status, headers)
|
35
|
-
|
36
|
-
response.set_cookie("cookie1", {:value => "chip1", :path => "/"})
|
37
|
-
response.set_cookie("cookie2", {:value => "chip2", :path => "/"})
|
38
|
-
response.finish
|
39
|
-
}
|
40
|
-
end
|
41
|
-
|
42
|
-
map "/basic-auth" do
|
43
|
-
use Rack::Auth::Basic, "basic-realm" do |username, password|
|
44
|
-
username == "admin" && password == "secret"
|
45
|
-
end
|
46
|
-
|
47
|
-
run lambda { |env|
|
48
|
-
IntegrationServer.respond_with "basic-auth"
|
49
|
-
}
|
50
|
-
end
|
51
|
-
|
52
|
-
map "/ntlm-auth" do
|
53
|
-
run lambda { |env|
|
54
|
-
resp = [401, {"WWW-Authenticate" => "NTLM\r\nNegotiate"}, []]
|
55
|
-
# head request 1: challenge & response (from actual server)
|
56
|
-
if env["HTTP_AUTHORIZATION"] =~ /(NTLM|Negotiate) TlRMTVNTUAABAAAAB4IIAA/
|
57
|
-
resp = [401, {
|
58
|
-
"Content-Type" => "text/html; charset=us-ascii",
|
59
|
-
"Server" => "Microsoft-HTTPAPI/2.0",
|
60
|
-
"WWW-Authenticate" => "#{$1} TlRMTVNTUAACAAAAEAAQADgAAAAFgooCj/AvDazHhQsAAAAAAAAAAGAAYABIAAAABgLwIwAAAA9OAFQATABNAFQARQBTAFQAAgAQAE4AVABMAE0AVABFAFMAVAABABAATgBUAEwATQBUAEUAUwBUAAQAEABuAHQAbABtAHQAZQBzAHQAAwAQAG4AdABsAG0AdABlAHMAdAAHAAgAfzQp037nzQEAAAAA",
|
61
|
-
"Date" => "Mon, 31 Dec 2012 17:46:55 GMT",
|
62
|
-
"Content-Length" => "341"
|
63
|
-
}, []]
|
64
|
-
elsif env["HTTP_AUTHORIZATION"] =~ /(NTLM|Negotiate) (.+)/
|
65
|
-
# request 2: serve content
|
66
|
-
resp = IntegrationServer.respond_with "ntlm-auth"
|
67
|
-
else
|
68
|
-
resp = [401, {
|
69
|
-
"Content-Type" => "text/html; charset=us-ascii",
|
70
|
-
"WWW-Authenticate" => "NTLM\r\nNegotiate",
|
71
|
-
"Server" => "Microsoft-HTTPAPI/2.0",
|
72
|
-
"Date" => "Mon, 31 Dec 2012 17:46:55 GMT",
|
73
|
-
"Content-Length" => "341"
|
74
|
-
}, []]
|
75
|
-
end
|
76
|
-
resp
|
77
|
-
}
|
78
|
-
end
|
79
|
-
|
80
|
-
map "/digest-auth" do
|
81
|
-
# Rack::Auth::Digest is removed in Rack 3.1
|
82
|
-
run lambda { |env|
|
83
|
-
IntegrationServer.respond_with "digest-auth"
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
|
-
end
|
88
|
-
end
|
@@ -1,83 +0,0 @@
|
|
1
|
-
require "puma"
|
2
|
-
require "puma/minissl"
|
3
|
-
|
4
|
-
require "integration/support/application"
|
5
|
-
|
6
|
-
class IntegrationServer
|
7
|
-
def self.run(options = {})
|
8
|
-
server = new(options)
|
9
|
-
server.run
|
10
|
-
server
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.ssl_ca_file; integration_fixture("ca_all.pem") end
|
14
|
-
def self.ssl_key_file; integration_fixture("server.key") end
|
15
|
-
def self.ssl_cert_file; integration_fixture("server.cert") end
|
16
|
-
|
17
|
-
def self.integration_fixture(file)
|
18
|
-
file = File.expand_path("../../fixtures/#{file}", __FILE__)
|
19
|
-
raise "No such file '#{file}'" unless File.exist? file
|
20
|
-
file
|
21
|
-
end
|
22
|
-
|
23
|
-
def initialize(options = {})
|
24
|
-
@app = Application
|
25
|
-
@host = options.fetch(:host, "localhost")
|
26
|
-
@port = options.fetch(:port, 17172)
|
27
|
-
@ssl = options.fetch(:ssl, false)
|
28
|
-
|
29
|
-
@server = Puma::Server.new(app, events)
|
30
|
-
|
31
|
-
if ssl?
|
32
|
-
add_ssl_listener
|
33
|
-
else
|
34
|
-
add_tcp_listener
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
attr_reader :app, :host, :port, :server
|
39
|
-
|
40
|
-
def url(path = nil)
|
41
|
-
protocol = ssl? ? "https" : "http"
|
42
|
-
File.join "#{protocol}://#{host}:#{port}/", path.to_s
|
43
|
-
end
|
44
|
-
|
45
|
-
def ssl?
|
46
|
-
@ssl
|
47
|
-
end
|
48
|
-
|
49
|
-
def run
|
50
|
-
server.run
|
51
|
-
end
|
52
|
-
|
53
|
-
def stop
|
54
|
-
server.stop(true)
|
55
|
-
end
|
56
|
-
|
57
|
-
private
|
58
|
-
|
59
|
-
def events
|
60
|
-
Puma::Events.new
|
61
|
-
end
|
62
|
-
|
63
|
-
def add_tcp_listener
|
64
|
-
server.add_tcp_listener(host, port)
|
65
|
-
rescue Errno::EADDRINUSE
|
66
|
-
raise "Panther is already running at #{url}"
|
67
|
-
end
|
68
|
-
|
69
|
-
def add_ssl_listener
|
70
|
-
server.add_ssl_listener(host, port, ssl_context)
|
71
|
-
end
|
72
|
-
|
73
|
-
def ssl_context
|
74
|
-
context = Puma::MiniSSL::Context.new
|
75
|
-
|
76
|
-
context.key = IntegrationServer.ssl_key_file
|
77
|
-
context.cert = IntegrationServer.ssl_cert_file
|
78
|
-
context.verify_mode = Puma::MiniSSL::VERIFY_NONE
|
79
|
-
|
80
|
-
context
|
81
|
-
end
|
82
|
-
|
83
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,23 +0,0 @@
|
|
1
|
-
require 'bundler'
|
2
|
-
Bundler.setup(:default, :development)
|
3
|
-
|
4
|
-
unless RUBY_PLATFORM =~ /java/
|
5
|
-
require 'simplecov'
|
6
|
-
|
7
|
-
SimpleCov.start do
|
8
|
-
add_filter 'spec'
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
require 'httpi'
|
13
|
-
require 'rspec'
|
14
|
-
|
15
|
-
RSpec.configure do |config|
|
16
|
-
config.mock_with :mocha
|
17
|
-
config.order = 'random'
|
18
|
-
end
|
19
|
-
|
20
|
-
HTTPI.log = false
|
21
|
-
|
22
|
-
require 'support/fixture'
|
23
|
-
require 'support/matchers'
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module ErrorHelper
|
2
|
-
|
3
|
-
class Expectation
|
4
|
-
|
5
|
-
def initialize(error, spec)
|
6
|
-
@error = error
|
7
|
-
@spec = spec
|
8
|
-
end
|
9
|
-
|
10
|
-
def to(tag_error)
|
11
|
-
@spec.expect(@error).to @spec.be_a(tag_error)
|
12
|
-
end
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
def expect_error(error_to_raise, message)
|
17
|
-
fake_error(error_to_raise, message)
|
18
|
-
rescue => error
|
19
|
-
Expectation.new(error, self)
|
20
|
-
end
|
21
|
-
|
22
|
-
def be_tagged_with(tag_error)
|
23
|
-
tag_error
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
data/spec/support/fixture.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
class Fixture
|
2
|
-
class << self
|
3
|
-
|
4
|
-
def xml
|
5
|
-
@xml ||= load :xml
|
6
|
-
end
|
7
|
-
|
8
|
-
def xml_dime
|
9
|
-
@xml_dime ||= load :xml_dime
|
10
|
-
end
|
11
|
-
|
12
|
-
def gzip
|
13
|
-
@gzip ||= load :xml, :gz
|
14
|
-
end
|
15
|
-
|
16
|
-
def dime
|
17
|
-
@dime ||= load :xml_dime, :dime
|
18
|
-
end
|
19
|
-
|
20
|
-
private
|
21
|
-
|
22
|
-
def load(fixture, type = :xml)
|
23
|
-
File.read File.expand_path("../../fixtures/#{fixture}.#{type}", __FILE__)
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
end
|