puffing-billy 3.0.0 → 3.0.1
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/billy/browsers/capybara.rb +13 -9
- data/lib/billy/version.rb +1 -1
- metadata +9 -73
- data/.github/workflows/ci.yml +0 -27
- data/.gitignore +0 -6
- data/.rspec +0 -2
- data/Dockerfile +0 -14
- data/Gemfile +0 -4
- data/Guardfile +0 -23
- data/Rakefile +0 -11
- data/bin/proxy.rb +0 -3
- data/examples/README.md +0 -1
- data/examples/facebook_api.html +0 -59
- data/examples/intercept_request.html +0 -10
- data/examples/post_api.html +0 -16
- data/examples/preflight_request.html +0 -22
- data/examples/tumblr_api.html +0 -22
- data/examples/tumblr_api_https.html +0 -22
- data/lib/tasks/billy.rake +0 -87
- data/log/.gitkeep +0 -0
- data/puffing-billy.gemspec +0 -41
- data/spec/features/examples/facebook_api_spec.rb +0 -23
- data/spec/features/examples/intercept_request_spec.rb +0 -31
- data/spec/features/examples/post_api_spec.rb +0 -15
- data/spec/features/examples/preflight_request_spec.rb +0 -29
- data/spec/features/examples/tumblr_api_spec.rb +0 -59
- data/spec/lib/billy/browsers/capybara_spec.rb +0 -28
- data/spec/lib/billy/cache_spec.rb +0 -158
- data/spec/lib/billy/handlers/cache_handler_spec.rb +0 -191
- data/spec/lib/billy/handlers/handler_spec.rb +0 -16
- data/spec/lib/billy/handlers/proxy_handler_spec.rb +0 -258
- data/spec/lib/billy/handlers/request_handler_spec.rb +0 -200
- data/spec/lib/billy/handlers/request_log_spec.rb +0 -74
- data/spec/lib/billy/handlers/stub_handler_spec.rb +0 -117
- data/spec/lib/billy/proxy_connection_spec.rb +0 -20
- data/spec/lib/billy/proxy_request_stub_spec.rb +0 -252
- data/spec/lib/billy/resource_utils_spec.rb +0 -55
- data/spec/lib/billy/ssl/authority_spec.rb +0 -84
- data/spec/lib/billy/ssl/certificate_chain_spec.rb +0 -39
- data/spec/lib/billy/ssl/certificate_spec.rb +0 -89
- data/spec/lib/billy/watir/watir_spec.rb +0 -18
- data/spec/lib/proxy_spec.rb +0 -431
- data/spec/spec_helper.rb +0 -52
- data/spec/support/test_server.rb +0 -79
data/spec/lib/proxy_spec.rb
DELETED
@@ -1,431 +0,0 @@
|
|
1
|
-
require 'spec_helper'
|
2
|
-
require 'resolv'
|
3
|
-
|
4
|
-
shared_examples_for 'a proxy server' do
|
5
|
-
it 'should proxy GET requests' do
|
6
|
-
expect(http.get('/echo').body).to eql 'GET /echo'
|
7
|
-
end
|
8
|
-
|
9
|
-
it 'should proxy POST requests' do
|
10
|
-
expect(http.post('/echo', foo: 'bar').body).to eql "POST /echo\nfoo=bar"
|
11
|
-
end
|
12
|
-
|
13
|
-
it 'should proxy PUT requests' do
|
14
|
-
expect(http.post('/echo', foo: 'bar').body).to eql "POST /echo\nfoo=bar"
|
15
|
-
end
|
16
|
-
|
17
|
-
it 'should proxy HEAD requests' do
|
18
|
-
expect(http.head('/echo').headers['HTTP-X-EchoServer']).to eql 'HEAD /echo'
|
19
|
-
end
|
20
|
-
|
21
|
-
it 'should proxy DELETE requests' do
|
22
|
-
expect(http.delete('/echo').body).to eql 'DELETE /echo'
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'should proxy OPTIONS requests' do
|
26
|
-
expect(http.run_request(:options, '/echo', nil, nil).body).to eql 'OPTIONS /echo'
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
30
|
-
shared_examples_for 'a request stub' do
|
31
|
-
it 'should stub GET requests' do
|
32
|
-
proxy.stub("#{url}/foo")
|
33
|
-
.and_return(text: 'hello, GET!')
|
34
|
-
expect(http.get('/foo').body).to eql 'hello, GET!'
|
35
|
-
end
|
36
|
-
|
37
|
-
it 'should stub GET response statuses' do
|
38
|
-
proxy.stub("#{url}/foo")
|
39
|
-
.and_return(code: 200)
|
40
|
-
expect(http.get('/foo').status).to eql 200
|
41
|
-
end
|
42
|
-
|
43
|
-
it 'should stub POST requests' do
|
44
|
-
proxy.stub("#{url}/bar", method: :post)
|
45
|
-
.and_return(text: 'hello, POST!')
|
46
|
-
expect(http.post('/bar', foo: :bar).body).to eql 'hello, POST!'
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'should stub PUT requests' do
|
50
|
-
proxy.stub("#{url}/baz", method: :put)
|
51
|
-
.and_return(text: 'hello, PUT!')
|
52
|
-
expect(http.put('/baz', foo: :bar).body).to eql 'hello, PUT!'
|
53
|
-
end
|
54
|
-
|
55
|
-
it 'should stub HEAD requests' do
|
56
|
-
proxy.stub("#{url}/bap", method: :head)
|
57
|
-
.and_return(headers: { 'HTTP-X-Hello' => 'hello, HEAD!' })
|
58
|
-
expect(http.head('/bap').headers['http-x-hello']).to eql 'hello, HEAD!'
|
59
|
-
end
|
60
|
-
|
61
|
-
it 'should stub DELETE requests' do
|
62
|
-
proxy.stub("#{url}/bam", method: :delete)
|
63
|
-
.and_return(text: 'hello, DELETE!')
|
64
|
-
expect(http.delete('/bam').body).to eql 'hello, DELETE!'
|
65
|
-
end
|
66
|
-
|
67
|
-
it 'should stub OPTIONS requests' do
|
68
|
-
proxy.stub("#{url}/bim", method: :options)
|
69
|
-
.and_return(text: 'hello, OPTIONS!')
|
70
|
-
expect(http.run_request(:options, '/bim', nil, nil).body).to eql 'hello, OPTIONS!'
|
71
|
-
end
|
72
|
-
|
73
|
-
it 'should expose the currently registered stubs' do
|
74
|
-
stub1 = proxy.stub("#{url}/foo", method: :options)
|
75
|
-
.and_return(text: 'hello, OPTIONS!')
|
76
|
-
stub2 = proxy.stub("#{url}/bar", method: :options)
|
77
|
-
.and_return(text: 'hello, OPTIONS!')
|
78
|
-
expect(proxy.stubs).to eql([stub2, stub1])
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
shared_examples_for 'a cache' do
|
83
|
-
context 'whitelisted GET requests' do
|
84
|
-
it 'should not be cached' do
|
85
|
-
assert_noncached_url
|
86
|
-
end
|
87
|
-
|
88
|
-
context 'with ports' do
|
89
|
-
before do
|
90
|
-
rack_app_url = URI(http.url_prefix)
|
91
|
-
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port}"]
|
92
|
-
end
|
93
|
-
|
94
|
-
it 'should not be cached ' do
|
95
|
-
assert_noncached_url
|
96
|
-
end
|
97
|
-
end
|
98
|
-
end
|
99
|
-
|
100
|
-
context 'non-whitelisted GET requests' do
|
101
|
-
before do
|
102
|
-
Billy.config.whitelist = []
|
103
|
-
end
|
104
|
-
|
105
|
-
it 'should be cached' do
|
106
|
-
assert_cached_url
|
107
|
-
end
|
108
|
-
|
109
|
-
context 'with ports' do
|
110
|
-
before do
|
111
|
-
rack_app_url = URI(http.url_prefix)
|
112
|
-
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port + 1}"]
|
113
|
-
end
|
114
|
-
|
115
|
-
it 'should be cached' do
|
116
|
-
assert_cached_url
|
117
|
-
end
|
118
|
-
end
|
119
|
-
end
|
120
|
-
|
121
|
-
context 'cache_whitelist GET requests' do
|
122
|
-
before do
|
123
|
-
Billy.config.whitelist = [http.host]
|
124
|
-
Billy.config.cache_whitelist = [http.host]
|
125
|
-
end
|
126
|
-
|
127
|
-
it 'should be cached' do
|
128
|
-
assert_cached_url
|
129
|
-
end
|
130
|
-
|
131
|
-
context 'with ports' do
|
132
|
-
before do
|
133
|
-
rack_app_url = URI(http.url_prefix)
|
134
|
-
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port + 1}"]
|
135
|
-
Billy.config.cache_whitelist = Billy.config.whitelist
|
136
|
-
end
|
137
|
-
|
138
|
-
it 'should be cached' do
|
139
|
-
assert_cached_url
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
143
|
-
|
144
|
-
context 'ignore_params GET requests' do
|
145
|
-
before do
|
146
|
-
Billy.config.ignore_params = ['/analytics']
|
147
|
-
end
|
148
|
-
|
149
|
-
it 'should be cached' do
|
150
|
-
r = http.get('/analytics?some_param=5')
|
151
|
-
expect(r.body).to eql 'GET /analytics'
|
152
|
-
expect do
|
153
|
-
expect do
|
154
|
-
r = http.get('/analytics?some_param=20')
|
155
|
-
end.to change { r.headers['HTTP-X-EchoCount'].to_i }.by(1)
|
156
|
-
end.to_not change { r.body }
|
157
|
-
end
|
158
|
-
end
|
159
|
-
|
160
|
-
context 'path_blacklist GET requests' do
|
161
|
-
before do
|
162
|
-
Billy.config.path_blacklist = ['/api']
|
163
|
-
end
|
164
|
-
|
165
|
-
it 'should be cached' do
|
166
|
-
assert_cached_url('/api')
|
167
|
-
end
|
168
|
-
|
169
|
-
context 'path_blacklist includes regex' do
|
170
|
-
before do
|
171
|
-
Billy.config.path_blacklist = [/widgets$/]
|
172
|
-
end
|
173
|
-
|
174
|
-
it 'should not cache a non-match' do
|
175
|
-
assert_noncached_url('/widgets/5/edit')
|
176
|
-
end
|
177
|
-
|
178
|
-
it 'should cache a match' do
|
179
|
-
assert_cached_url('/widgets')
|
180
|
-
end
|
181
|
-
end
|
182
|
-
end
|
183
|
-
|
184
|
-
context 'cache persistence' do
|
185
|
-
let(:cache_path) { Billy.config.cache_path }
|
186
|
-
let(:cached_key) { proxy.cache.key('get', "#{url}/foo", '') }
|
187
|
-
let(:cached_file) do
|
188
|
-
f = cached_key + '.yml'
|
189
|
-
File.join(cache_path, f)
|
190
|
-
end
|
191
|
-
|
192
|
-
before do
|
193
|
-
Billy.config.whitelist = []
|
194
|
-
Dir.mkdir(cache_path) unless Dir.exist?(cache_path)
|
195
|
-
end
|
196
|
-
|
197
|
-
after do
|
198
|
-
File.delete(cached_file) if File.exist?(cached_file)
|
199
|
-
end
|
200
|
-
|
201
|
-
context 'enabled' do
|
202
|
-
before { Billy.config.persist_cache = true }
|
203
|
-
|
204
|
-
it 'should persist' do
|
205
|
-
http.get('/foo')
|
206
|
-
expect(File.exist?(cached_file)).to be true
|
207
|
-
end
|
208
|
-
|
209
|
-
it 'should be read initially from persistent cache' do
|
210
|
-
File.open(cached_file, 'w') do |f|
|
211
|
-
cached = {
|
212
|
-
headers: {},
|
213
|
-
content: 'GET /foo cached'
|
214
|
-
}
|
215
|
-
f.write(cached.to_yaml(Encoding: :Utf8))
|
216
|
-
end
|
217
|
-
|
218
|
-
r = http.get('/foo')
|
219
|
-
expect(r.body).to eql 'GET /foo cached'
|
220
|
-
end
|
221
|
-
|
222
|
-
context 'cache_request_headers requests' do
|
223
|
-
it 'should not be cached by default' do
|
224
|
-
http.get('/foo')
|
225
|
-
saved_cache = Billy.proxy.cache.fetch_from_persistence(cached_key)
|
226
|
-
expect(saved_cache.keys).not_to include :request_headers
|
227
|
-
end
|
228
|
-
|
229
|
-
context 'when enabled' do
|
230
|
-
before do
|
231
|
-
Billy.config.cache_request_headers = true
|
232
|
-
end
|
233
|
-
|
234
|
-
it 'should be cached' do
|
235
|
-
http.get('/foo')
|
236
|
-
saved_cache = Billy.proxy.cache.fetch_from_persistence(cached_key)
|
237
|
-
expect(saved_cache.keys).to include :request_headers
|
238
|
-
end
|
239
|
-
end
|
240
|
-
end
|
241
|
-
|
242
|
-
context 'ignore_cache_port requests' do
|
243
|
-
it 'should be cached without port' do
|
244
|
-
r = http.get('/foo')
|
245
|
-
url = URI(r.env[:url])
|
246
|
-
saved_cache = Billy.proxy.cache.fetch_from_persistence(cached_key)
|
247
|
-
|
248
|
-
expect(saved_cache[:url]).to_not eql(url.to_s)
|
249
|
-
expect(saved_cache[:url]).to eql(url.to_s.gsub(":#{url.port}", ''))
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
|
-
context 'non_whitelisted_requests_disabled requests' do
|
254
|
-
before { Billy.config.non_whitelisted_requests_disabled = true }
|
255
|
-
|
256
|
-
it 'should raise error when disabled' do
|
257
|
-
# TODO: Suppress stderr output: https://gist.github.com/adamstegman/926858
|
258
|
-
expect { http.get('/foo') }.to raise_error(Faraday::ConnectionFailed, 'end of file reached')
|
259
|
-
end
|
260
|
-
end
|
261
|
-
|
262
|
-
context 'non_successful_cache_disabled requests' do
|
263
|
-
before do
|
264
|
-
rack_app_url = URI(http_error.url_prefix)
|
265
|
-
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port}"]
|
266
|
-
Billy.config.non_successful_cache_disabled = true
|
267
|
-
end
|
268
|
-
|
269
|
-
it 'should not cache non-successful response when enabled' do
|
270
|
-
http_error.get('/foo')
|
271
|
-
expect(File.exist?(cached_file)).to be false
|
272
|
-
end
|
273
|
-
|
274
|
-
it 'should cache successful response when enabled' do
|
275
|
-
assert_cached_url
|
276
|
-
end
|
277
|
-
end
|
278
|
-
|
279
|
-
context 'non_successful_error_level requests' do
|
280
|
-
before do
|
281
|
-
rack_app_url = URI(http_error.url_prefix)
|
282
|
-
Billy.config.whitelist = ["#{rack_app_url.host}:#{rack_app_url.port}"]
|
283
|
-
Billy.config.non_successful_error_level = :error
|
284
|
-
end
|
285
|
-
|
286
|
-
it 'should raise error for non-successful responses when :error' do
|
287
|
-
expect { http_error.get('/foo') }.to raise_error(Faraday::ConnectionFailed)
|
288
|
-
end
|
289
|
-
end
|
290
|
-
end
|
291
|
-
|
292
|
-
context 'disabled' do
|
293
|
-
before { Billy.config.persist_cache = false }
|
294
|
-
|
295
|
-
it 'shouldnt persist' do
|
296
|
-
http.get('/foo')
|
297
|
-
expect(File.exist?(cached_file)).to be false
|
298
|
-
end
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
def assert_noncached_url(url = '/foo')
|
303
|
-
r = http.get(url)
|
304
|
-
expect(r.body).to eql "GET #{url}"
|
305
|
-
expect do
|
306
|
-
expect do
|
307
|
-
r = http.get(url)
|
308
|
-
end.to change { r.headers['HTTP-X-EchoCount'].to_i }.by(1)
|
309
|
-
end.to_not change { r.body }
|
310
|
-
end
|
311
|
-
|
312
|
-
def assert_cached_url(url = '/foo')
|
313
|
-
r = http.get(url)
|
314
|
-
expect(r.body).to eql "GET #{url}"
|
315
|
-
expect do
|
316
|
-
expect do
|
317
|
-
r = http.get(url)
|
318
|
-
end.to_not change { r.headers['HTTP-X-EchoCount'] }
|
319
|
-
end.to_not change { r.body }
|
320
|
-
end
|
321
|
-
end
|
322
|
-
|
323
|
-
describe Billy::Proxy do
|
324
|
-
before do
|
325
|
-
# Adding non-valid Faraday options throw an error: https://github.com/arsduo/koala/pull/311
|
326
|
-
# Valid options: :request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class
|
327
|
-
faraday_options = {
|
328
|
-
proxy: { uri: proxy.url },
|
329
|
-
request: { timeout: 1.0 }
|
330
|
-
}
|
331
|
-
faraday_ssl_options = faraday_options.merge(ssl: {
|
332
|
-
verify: true,
|
333
|
-
ca_file: Billy.certificate_authority.cert_file
|
334
|
-
})
|
335
|
-
|
336
|
-
@http = Faraday.new @http_url, faraday_options
|
337
|
-
@https = Faraday.new @https_url, faraday_ssl_options
|
338
|
-
@http_error = Faraday.new @error_url, faraday_options
|
339
|
-
end
|
340
|
-
|
341
|
-
context 'proxying' do
|
342
|
-
context 'HTTP' do
|
343
|
-
let!(:http) { @http }
|
344
|
-
it_should_behave_like 'a proxy server'
|
345
|
-
end
|
346
|
-
|
347
|
-
context 'HTTPS' do
|
348
|
-
let!(:http) { @https }
|
349
|
-
it_should_behave_like 'a proxy server'
|
350
|
-
end
|
351
|
-
end
|
352
|
-
|
353
|
-
context 'stubbing' do
|
354
|
-
context 'HTTP' do
|
355
|
-
let!(:url) { @http_url }
|
356
|
-
let!(:http) { @http }
|
357
|
-
it_should_behave_like 'a request stub'
|
358
|
-
end
|
359
|
-
|
360
|
-
context 'HTTPS' do
|
361
|
-
let!(:url) { @https_url }
|
362
|
-
let!(:http) { @https }
|
363
|
-
it_should_behave_like 'a request stub'
|
364
|
-
end
|
365
|
-
end
|
366
|
-
|
367
|
-
context 'caching' do
|
368
|
-
it 'defaults to nil scope' do
|
369
|
-
expect(proxy.cache.scope).to be nil
|
370
|
-
end
|
371
|
-
|
372
|
-
context 'HTTP' do
|
373
|
-
let!(:url) { @http_url }
|
374
|
-
let!(:http) { @http }
|
375
|
-
let!(:http_error) { @http_error }
|
376
|
-
it_should_behave_like 'a cache'
|
377
|
-
end
|
378
|
-
|
379
|
-
context 'HTTPS' do
|
380
|
-
let!(:url) { @https_url }
|
381
|
-
let!(:http) { @https }
|
382
|
-
let!(:http_error) { @http_error }
|
383
|
-
it_should_behave_like 'a cache'
|
384
|
-
end
|
385
|
-
|
386
|
-
context 'with a cache scope' do
|
387
|
-
let!(:url) { @http_url }
|
388
|
-
let!(:http) { @http }
|
389
|
-
let!(:http_error) { @http_error }
|
390
|
-
|
391
|
-
before do
|
392
|
-
proxy.cache.scope_to 'my_cache'
|
393
|
-
end
|
394
|
-
|
395
|
-
after do
|
396
|
-
proxy.cache.use_default_scope
|
397
|
-
end
|
398
|
-
|
399
|
-
it_should_behave_like 'a cache'
|
400
|
-
|
401
|
-
it 'uses the cache scope' do
|
402
|
-
expect(proxy.cache.scope).to eq('my_cache')
|
403
|
-
end
|
404
|
-
|
405
|
-
it 'can be reset to the default scope' do
|
406
|
-
proxy.cache.use_default_scope
|
407
|
-
expect(proxy.cache.scope).to be nil
|
408
|
-
end
|
409
|
-
|
410
|
-
it 'can execute a block against a cache scope' do
|
411
|
-
expect(proxy.cache.scope).to eq 'my_cache'
|
412
|
-
proxy.cache.with_scope 'another_cache' do
|
413
|
-
expect(proxy.cache.scope).to eq 'another_cache'
|
414
|
-
end
|
415
|
-
expect(proxy.cache.scope).to eq 'my_cache'
|
416
|
-
end
|
417
|
-
|
418
|
-
it 'requires a block to be passed to with_scope' do
|
419
|
-
expect { proxy.cache.with_scope 'some_scope' }.to raise_error ArgumentError
|
420
|
-
end
|
421
|
-
|
422
|
-
it 'should have different keys for the same request under a different scope' do
|
423
|
-
args = ['get', "#{url}/foo", '']
|
424
|
-
key = proxy.cache.key(*args)
|
425
|
-
proxy.cache.with_scope 'another_cache' do
|
426
|
-
expect(proxy.cache.key(*args)).to_not eq key
|
427
|
-
end
|
428
|
-
end
|
429
|
-
end
|
430
|
-
end
|
431
|
-
end
|
data/spec/spec_helper.rb
DELETED
@@ -1,52 +0,0 @@
|
|
1
|
-
Dir[File.expand_path('../support/**/*.rb', __FILE__)].each { |f| require f }
|
2
|
-
|
3
|
-
require 'pry'
|
4
|
-
require 'billy/capybara/rspec'
|
5
|
-
require 'billy/watir/rspec'
|
6
|
-
require 'rack'
|
7
|
-
require 'logger'
|
8
|
-
require 'fileutils'
|
9
|
-
require 'webdrivers'
|
10
|
-
|
11
|
-
$stdout.puts `#{::Selenium::WebDriver::Chrome::Service.driver_path.call} --version` if ENV['CI']
|
12
|
-
|
13
|
-
browser = Billy::Browsers::Watir.new :chrome
|
14
|
-
|
15
|
-
Capybara.configure do |config|
|
16
|
-
config.app = Rack::Directory.new(File.expand_path('../../examples', __FILE__))
|
17
|
-
config.server = :webrick
|
18
|
-
config.javascript_driver = :selenium_chrome_headless_billy
|
19
|
-
end
|
20
|
-
|
21
|
-
Billy.configure do |config|
|
22
|
-
config.logger = Logger.new(File.expand_path('../../log/test.log', __FILE__))
|
23
|
-
end
|
24
|
-
|
25
|
-
RSpec.configure do |config|
|
26
|
-
include Billy::TestServer
|
27
|
-
config.run_all_when_everything_filtered = true
|
28
|
-
config.filter_run :focus
|
29
|
-
config.order = 'random'
|
30
|
-
|
31
|
-
config.before :suite do
|
32
|
-
FileUtils.rm_rf(Billy.config.certs_path)
|
33
|
-
FileUtils.rm_rf(Billy.config.cache_path)
|
34
|
-
end
|
35
|
-
|
36
|
-
config.before :all do
|
37
|
-
start_test_servers
|
38
|
-
@browser = browser
|
39
|
-
end
|
40
|
-
|
41
|
-
config.before :each do
|
42
|
-
proxy.reset_cache
|
43
|
-
end
|
44
|
-
|
45
|
-
config.after :each do
|
46
|
-
Billy.config.reset
|
47
|
-
end
|
48
|
-
|
49
|
-
config.after :suite do
|
50
|
-
browser.close
|
51
|
-
end
|
52
|
-
end
|
data/spec/support/test_server.rb
DELETED
@@ -1,79 +0,0 @@
|
|
1
|
-
require 'eventmachine'
|
2
|
-
require 'thin'
|
3
|
-
require 'faraday'
|
4
|
-
|
5
|
-
module Thin::Backends
|
6
|
-
class TcpServer
|
7
|
-
def get_port
|
8
|
-
# seriously, eventmachine, how hard does getting a port have to be?
|
9
|
-
Socket.unpack_sockaddr_in(EM.get_sockname(@signature)).first
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
|
-
module Billy
|
15
|
-
module TestServer
|
16
|
-
def initialize
|
17
|
-
Thin::Logging.silent = true
|
18
|
-
end
|
19
|
-
|
20
|
-
def start_test_servers
|
21
|
-
q = Queue.new
|
22
|
-
Thread.new do
|
23
|
-
EM.run do
|
24
|
-
echo = echo_app_setup
|
25
|
-
|
26
|
-
http_server = start_server(echo)
|
27
|
-
q.push http_server.backend.get_port
|
28
|
-
|
29
|
-
https_server = start_server(echo, true)
|
30
|
-
q.push https_server.backend.get_port
|
31
|
-
|
32
|
-
echo_error = echo_app_setup(500)
|
33
|
-
error_server = start_server(echo_error)
|
34
|
-
q.push error_server.backend.get_port
|
35
|
-
end
|
36
|
-
end
|
37
|
-
|
38
|
-
@http_url = "http://127.0.0.1:#{q.pop}"
|
39
|
-
@https_url = "https://127.0.0.1:#{q.pop}"
|
40
|
-
@error_url = "http://127.0.0.1:#{q.pop}"
|
41
|
-
end
|
42
|
-
|
43
|
-
def echo_app_setup(response_code = 200)
|
44
|
-
counter = 0
|
45
|
-
Proc.new do |env|
|
46
|
-
req_body = env['rack.input'].read
|
47
|
-
request_info = "#{env['REQUEST_METHOD']} #{env['PATH_INFO']}"
|
48
|
-
res_body = request_info
|
49
|
-
res_body += "\n#{req_body}" unless req_body.empty?
|
50
|
-
counter += 1
|
51
|
-
[
|
52
|
-
response_code,
|
53
|
-
{ 'HTTP-X-EchoServer' => request_info,
|
54
|
-
'HTTP-X-EchoCount' => "#{counter}" },
|
55
|
-
[res_body]
|
56
|
-
]
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def certificate_chain(domain)
|
61
|
-
ca = Billy.certificate_authority.cert
|
62
|
-
cert = Billy::Certificate.new(domain)
|
63
|
-
chain = Billy::CertificateChain.new(domain, cert.cert, ca)
|
64
|
-
{ private_key_file: cert.key_file,
|
65
|
-
cert_chain_file: chain.file }
|
66
|
-
|
67
|
-
end
|
68
|
-
|
69
|
-
def start_server(echo, ssl = false)
|
70
|
-
http_server = Thin::Server.new '127.0.0.1', 0, echo
|
71
|
-
if ssl
|
72
|
-
http_server.ssl = true
|
73
|
-
http_server.ssl_options = certificate_chain('localhost')
|
74
|
-
end
|
75
|
-
http_server.start
|
76
|
-
http_server
|
77
|
-
end
|
78
|
-
end
|
79
|
-
end
|