puffing-billy 2.2.0 → 2.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +27 -24
- data/examples/tumblr_api_https.html +22 -0
- data/lib/billy/browsers/capybara.rb +2 -0
- data/lib/billy/config.rb +2 -1
- data/lib/billy/handlers/proxy_handler.rb +11 -1
- data/lib/billy/version.rb +1 -1
- data/spec/lib/billy/browsers/capybara_spec.rb +28 -0
- data/spec/lib/billy/handlers/proxy_handler_spec.rb +28 -0
- data/spec/lib/proxy_spec.rb +23 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9abe93dc66216bc06e928bc9b61d92c52aaa718c196664afbaece19ef9dedd06
|
4
|
+
data.tar.gz: 76967de33848f166cc247c0a20ac917537331293237e33d8a5693fd1756221ba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 234b170df43cc3954a49e7fdae65593b1de7e07b0ae4fc3e68dfc9da620c348d700af14f533d379448f1da764cd484f2e07752b2254d59c602b76d96ebb14449
|
7
|
+
data.tar.gz: 21e5760521c6c6d74d9a969834cc1856f780f98350665793a3028140f8b2f738a4df6060a2d8043946d977b6f504c74625df12a763fc7e8b29619f9aba7c8423
|
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,8 @@
|
|
1
|
+
v2.3.0, 2019-12-26
|
2
|
+
-------------------
|
3
|
+
* Add `cache_whitelist` config option [#279](https://github.com/oesmith/puffing-billy/pull/279)
|
4
|
+
* Ignore certificate errors in Chrome [#280](https://github.com/oesmith/puffing-billy/pull/280)
|
5
|
+
|
1
6
|
v2.2.0, 2019-10-26
|
2
7
|
-------------------
|
3
8
|
* Before handle request method [#273](https://github.com/oesmith/puffing-billy/pull/273)
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ you can test it!
|
|
21
21
|
|
22
22
|
```ruby
|
23
23
|
it 'should stub google' do
|
24
|
-
proxy.stub('http://www.google.com/').and_return(:
|
24
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
25
25
|
visit 'http://www.google.com/'
|
26
26
|
expect(page).to have_content("I'm not Google!")
|
27
27
|
end
|
@@ -85,21 +85,21 @@ require 'billy/watir/rspec'
|
|
85
85
|
|
86
86
|
```ruby
|
87
87
|
# Stub and return text, json, jsonp (or anything else)
|
88
|
-
proxy.stub('http://example.com/text/').and_return(:
|
89
|
-
proxy.stub('http://example.com/json/').and_return(:
|
90
|
-
proxy.stub('http://example.com/jsonp/').and_return(:
|
91
|
-
proxy.stub('http://example.com/headers/').and_return(
|
92
|
-
:
|
93
|
-
:
|
94
|
-
|
95
|
-
proxy.stub('http://example.com/wtf/').and_return(:
|
88
|
+
proxy.stub('http://example.com/text/').and_return(text: 'Foobar')
|
89
|
+
proxy.stub('http://example.com/json/').and_return(json: { foo: 'bar' })
|
90
|
+
proxy.stub('http://example.com/jsonp/').and_return(jsonp: { foo: 'bar' })
|
91
|
+
proxy.stub('http://example.com/headers/').and_return(
|
92
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
93
|
+
json: { foo: 'bar' }
|
94
|
+
)
|
95
|
+
proxy.stub('http://example.com/wtf/').and_return(body: 'WTF!?', content_type: 'text/wtf')
|
96
96
|
|
97
97
|
# Stub redirections and other return codes
|
98
|
-
proxy.stub('http://example.com/redirect/').and_return(:
|
99
|
-
proxy.stub('http://example.com/missing/').and_return(:
|
98
|
+
proxy.stub('http://example.com/redirect/').and_return(redirect_to: 'http://example.com/other')
|
99
|
+
proxy.stub('http://example.com/missing/').and_return(code: 404, body: 'Not found')
|
100
100
|
|
101
101
|
# Even stub HTTPS!
|
102
|
-
proxy.stub('https://example.com:443/secure/').and_return(:
|
102
|
+
proxy.stub('https://example.com:443/secure/').and_return(text: 'secrets!!1!')
|
103
103
|
|
104
104
|
# Pass a Proc (or Proc-style object) to create dynamic responses.
|
105
105
|
#
|
@@ -111,8 +111,8 @@ proxy.stub('https://example.com:443/secure/').and_return(:text => 'secrets!!1!')
|
|
111
111
|
# method: The HTTP verb which was requested
|
112
112
|
proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers, body, url, method|
|
113
113
|
{
|
114
|
-
:
|
115
|
-
:
|
114
|
+
code: 200,
|
115
|
+
text: "Hello, #{params['name'][0]}"
|
116
116
|
}
|
117
117
|
})
|
118
118
|
|
@@ -122,7 +122,7 @@ proxy.stub('https://example.com/proc/').and_return(Proc.new { |params, headers,
|
|
122
122
|
# server. The scope of the delivered callable is the user scope where
|
123
123
|
# it was defined. Setting method to 'all' will intercept requests regardless of
|
124
124
|
# the method.
|
125
|
-
proxy.stub('http://example.com/', method
|
125
|
+
proxy.stub('http://example.com/', method: 'all').and_return(Proc.new { |*args|
|
126
126
|
response = Billy.pass_request(*args)
|
127
127
|
response[:headers]['Content-Type'] = 'text/plain'
|
128
128
|
response[:body] = 'Hello World!'
|
@@ -131,19 +131,19 @@ proxy.stub('http://example.com/', method => 'all').and_return(Proc.new { |*args|
|
|
131
131
|
})
|
132
132
|
|
133
133
|
# Stub out a POST. Don't forget to allow a CORS request and set the method to 'post'
|
134
|
-
proxy.stub('http://example.com/api', :
|
135
|
-
:
|
136
|
-
:
|
134
|
+
proxy.stub('http://example.com/api', method: 'post').and_return(
|
135
|
+
headers: { 'Access-Control-Allow-Origin' => '*' },
|
136
|
+
code: 201
|
137
137
|
)
|
138
138
|
|
139
139
|
# Stub out an OPTIONS request. Set the headers to the values you require.
|
140
|
-
proxy.stub('http://example.com/api', :
|
141
|
-
:
|
140
|
+
proxy.stub('http://example.com/api', method: 'options').and_return(
|
141
|
+
headers: {
|
142
142
|
'Access-Control-Allow-Methods' => 'GET, PATCH, POST, PUT, OPTIONS',
|
143
143
|
'Access-Control-Allow-Headers' => 'X-Requested-With, X-Prototype-Version, Content-Type',
|
144
144
|
'Access-Control-Allow-Origin' => '*'
|
145
145
|
},
|
146
|
-
:
|
146
|
+
code: 200
|
147
147
|
)
|
148
148
|
```
|
149
149
|
|
@@ -154,7 +154,7 @@ If for any reason you'd need to reset stubs manually you can do it in two ways:
|
|
154
154
|
|
155
155
|
```ruby
|
156
156
|
# reset a single stub
|
157
|
-
example_stub = proxy.stub('http://example.com/text/').and_return(:
|
157
|
+
example_stub = proxy.stub('http://example.com/text/').and_return(text: 'Foobar')
|
158
158
|
proxy.unstub example_stub
|
159
159
|
|
160
160
|
# reset all stubs
|
@@ -193,7 +193,7 @@ Before('@billy') do
|
|
193
193
|
end
|
194
194
|
|
195
195
|
And /^a stub for google$/ do
|
196
|
-
proxy.stub('http://www.google.com/').and_return(:
|
196
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
197
197
|
visit 'http://www.google.com/'
|
198
198
|
expect(page).to have_content("I'm not Google!")
|
199
199
|
end
|
@@ -224,7 +224,7 @@ Before('@billy') do
|
|
224
224
|
end
|
225
225
|
|
226
226
|
And /^a stub for google$/ do
|
227
|
-
proxy.stub('http://www.google.com/').and_return(:
|
227
|
+
proxy.stub('http://www.google.com/').and_return(text: "I'm not Google!")
|
228
228
|
@browser.goto 'http://www.google.com/'
|
229
229
|
expect(@browser.text).to eq("I'm not Google!")
|
230
230
|
end
|
@@ -263,6 +263,8 @@ server = Capybara.current_session.server
|
|
263
263
|
Billy.config.whitelist = ["#{server.host}:#{server.port}"]
|
264
264
|
```
|
265
265
|
|
266
|
+
If you would like to cache whitelisted URLs, you can define them in `c.cache_whitelist`. This is useful for scenarios where you may want to set `c.non_whitelisted_requests_disabled` to `true` to only allow whitelisted URLs to be accessed, but still allow specific URLs to be treated as if they were non-whitelisted.
|
267
|
+
|
266
268
|
If you want to use puffing-billy like you would [VCR](https://github.com/vcr/vcr)
|
267
269
|
you can turn on cache persistence. This way you don't have to manually mock out
|
268
270
|
everything as requests are automatically recorded and played back. With cache
|
@@ -292,6 +294,7 @@ Billy.configure do |c|
|
|
292
294
|
c.proxy_port = 12345 # defaults to random
|
293
295
|
c.proxied_request_host = nil
|
294
296
|
c.proxied_request_port = 80
|
297
|
+
c.cache_whitelist = []
|
295
298
|
c.record_requests = true # defaults to false
|
296
299
|
c.cache_request_body_methods = ['post', 'patch', 'put'] # defaults to ['post']
|
297
300
|
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
<!doctype html>
|
2
|
+
<body>
|
3
|
+
<h1>Latest news</h1>
|
4
|
+
<div id="news"></div>
|
5
|
+
|
6
|
+
<script type='text/javascript' src='http://code.jquery.com/jquery-1.8.2.min.js'></script>
|
7
|
+
<script type='text/javascript'>
|
8
|
+
$(function () {
|
9
|
+
var url = 'https://blog.howmanyleft.co.uk/api/read/json?callback=?&type=text&num=3&filter=text';
|
10
|
+
$.getJSON(url, function (data) {
|
11
|
+
$.each(data.posts, function (idx, post) {
|
12
|
+
var title = post['regular-title'];
|
13
|
+
var href = post['url-with-slug'];
|
14
|
+
var body = post['regular-body'];
|
15
|
+
$('#news').append(
|
16
|
+
'<h3><a href="' + href + '">' + title + '</a></h3>' +
|
17
|
+
'<p>' + body + '</p>');
|
18
|
+
});
|
19
|
+
});
|
20
|
+
})
|
21
|
+
</script>
|
22
|
+
</body>
|
@@ -64,6 +64,7 @@ module Billy
|
|
64
64
|
|
65
65
|
::Capybara.register_driver :selenium_chrome_billy do |app|
|
66
66
|
options = Selenium::WebDriver::Chrome::Options.new
|
67
|
+
options.add_argument('--ignore-certificate-errors')
|
67
68
|
options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
|
68
69
|
|
69
70
|
::Capybara::Selenium::Driver.new(
|
@@ -79,6 +80,7 @@ module Billy
|
|
79
80
|
options = Selenium::WebDriver::Chrome::Options.new
|
80
81
|
options.headless!
|
81
82
|
options.add_argument('--enable-features=NetworkService,NetworkServiceInProcess')
|
83
|
+
options.add_argument('--ignore-certificate-errors')
|
82
84
|
options.add_argument("--proxy-server=#{Billy.proxy.host}:#{Billy.proxy.port}")
|
83
85
|
options.add_argument('--disable-gpu') if Gem.win_platform?
|
84
86
|
options.add_argument('--no-sandbox') if ENV['CI']
|
data/lib/billy/config.rb
CHANGED
@@ -6,7 +6,7 @@ module Billy
|
|
6
6
|
DEFAULT_WHITELIST = ['127.0.0.1', 'localhost']
|
7
7
|
RANDOM_AVAILABLE_PORT = 0 # https://github.com/eventmachine/eventmachine/wiki/FAQ#wiki-can-i-start-a-server-on-a-random-available-port
|
8
8
|
|
9
|
-
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :path_blacklist, :ignore_params, :allow_params,
|
9
|
+
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :cache_whitelist, :path_blacklist, :ignore_params, :allow_params,
|
10
10
|
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
|
11
11
|
:non_whitelisted_requests_disabled, :cache_path, :certs_path, :proxy_host, :proxy_port, :proxied_request_inactivity_timeout,
|
12
12
|
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :dynamic_jsonp_callback_name, :merge_cached_responses_whitelist,
|
@@ -21,6 +21,7 @@ module Billy
|
|
21
21
|
def reset
|
22
22
|
@cache = true
|
23
23
|
@cache_request_headers = false
|
24
|
+
@cache_whitelist = []
|
24
25
|
@whitelist = DEFAULT_WHITELIST
|
25
26
|
@path_blacklist = []
|
26
27
|
@merge_cached_responses_whitelist = []
|
@@ -110,7 +110,7 @@ module Billy
|
|
110
110
|
|
111
111
|
url = Addressable::URI.parse(url)
|
112
112
|
# Cache the responses if they aren't whitelisted host[:port]s but always cache blacklisted paths on any hosts
|
113
|
-
cacheable_status?(status) && (!whitelisted_url?(url) || blacklisted_path?(url.path))
|
113
|
+
cacheable_status?(status) && (!whitelisted_url?(url) || blacklisted_path?(url.path) || cache_whitelisted_url?(url))
|
114
114
|
end
|
115
115
|
|
116
116
|
def whitelisted_url?(url)
|
@@ -123,6 +123,16 @@ module Billy
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
def cache_whitelisted_url?(url)
|
127
|
+
Billy.config.cache_whitelist.any? do |value|
|
128
|
+
if value.is_a?(Regexp)
|
129
|
+
url.to_s =~ value || url.omit(:port).to_s =~ value
|
130
|
+
else
|
131
|
+
value =~ /^#{url.host}(?::#{url.port})?$/
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
126
136
|
def blacklisted_path?(path)
|
127
137
|
!Billy.config.path_blacklist.index { |bl| bl.is_a?(Regexp) ? path =~ bl : path.include?(bl) }.nil?
|
128
138
|
end
|
data/lib/billy/version.rb
CHANGED
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe 'Capybara drivers', type: :feature, js: true do
|
4
|
+
it 'allows HTTPS calls' do
|
5
|
+
proxy.stub('https://blog.howmanyleft.co.uk:443/api/read/json').and_return(
|
6
|
+
jsonp: {
|
7
|
+
posts: [
|
8
|
+
{
|
9
|
+
'regular-title' => 'News Item 1',
|
10
|
+
'url-with-slug' => 'http://example.com/news/1',
|
11
|
+
'regular-body' => 'News item 1 content here'
|
12
|
+
},
|
13
|
+
{
|
14
|
+
'regular-title' => 'News Item 2',
|
15
|
+
'url-with-slug' => 'http://example.com/news/2',
|
16
|
+
'regular-body' => 'News item 2 content here'
|
17
|
+
}
|
18
|
+
]
|
19
|
+
})
|
20
|
+
|
21
|
+
visit '/tumblr_api_https.html'
|
22
|
+
|
23
|
+
expect(page).to have_link('News Item 1', href: 'http://example.com/news/1')
|
24
|
+
expect(page).to have_content('News item 1 content here')
|
25
|
+
expect(page).to have_link('News Item 2', href: 'http://example.com/news/2')
|
26
|
+
expect(page).to have_content('News item 2 content here')
|
27
|
+
end
|
28
|
+
end
|
@@ -175,6 +175,34 @@ describe Billy::ProxyHandler do
|
|
175
175
|
request[:body])
|
176
176
|
end
|
177
177
|
|
178
|
+
it 'does NOT cache the response if the host is whitelisted but not cache_whitelisted' do
|
179
|
+
uri = Addressable::URI.parse(request[:url])
|
180
|
+
|
181
|
+
expect(subject).to receive(:allowed_response_code?).and_return(true)
|
182
|
+
expect(Billy.config).to receive(:whitelist).and_return([uri.host])
|
183
|
+
expect(Billy.config).to receive(:cache_whitelist).and_return([])
|
184
|
+
|
185
|
+
expect(Billy::Cache.instance).not_to receive(:store)
|
186
|
+
subject.handle_request(request[:method],
|
187
|
+
request[:url],
|
188
|
+
request[:headers],
|
189
|
+
request[:body])
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'caches the response if the host is whitelisted AND cache_whitelisted' do
|
193
|
+
uri = Addressable::URI.parse(request[:url])
|
194
|
+
|
195
|
+
expect(subject).to receive(:allowed_response_code?).and_return(true)
|
196
|
+
expect(Billy.config).to receive(:whitelist).and_return([uri.host])
|
197
|
+
expect(Billy.config).to receive(:cache_whitelist).and_return([uri.host])
|
198
|
+
|
199
|
+
expect(Billy::Cache.instance).to receive(:store)
|
200
|
+
subject.handle_request(request[:method],
|
201
|
+
request[:url],
|
202
|
+
request[:headers],
|
203
|
+
request[:body])
|
204
|
+
end
|
205
|
+
|
178
206
|
it 'uses the timeouts defined in configuration' do
|
179
207
|
allow(Billy.config).to receive(:proxied_request_inactivity_timeout).and_return(42)
|
180
208
|
allow(Billy.config).to receive(:proxied_request_connect_timeout).and_return(24)
|
data/spec/lib/proxy_spec.rb
CHANGED
@@ -118,6 +118,29 @@ shared_examples_for 'a cache' do
|
|
118
118
|
end
|
119
119
|
end
|
120
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
|
+
|
121
144
|
context 'ignore_params GET requests' do
|
122
145
|
before do
|
123
146
|
Billy.config.ignore_params = ['/analytics']
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puffing-billy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Olly Smith
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-
|
11
|
+
date: 2019-12-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -336,6 +336,7 @@ files:
|
|
336
336
|
- examples/post_api.html
|
337
337
|
- examples/preflight_request.html
|
338
338
|
- examples/tumblr_api.html
|
339
|
+
- examples/tumblr_api_https.html
|
339
340
|
- lib/billy.rb
|
340
341
|
- lib/billy/browsers/capybara.rb
|
341
342
|
- lib/billy/browsers/watir.rb
|
@@ -375,6 +376,7 @@ files:
|
|
375
376
|
- spec/features/examples/post_api_spec.rb
|
376
377
|
- spec/features/examples/preflight_request_spec.rb
|
377
378
|
- spec/features/examples/tumblr_api_spec.rb
|
379
|
+
- spec/lib/billy/browsers/capybara_spec.rb
|
378
380
|
- spec/lib/billy/cache_spec.rb
|
379
381
|
- spec/lib/billy/handlers/cache_handler_spec.rb
|
380
382
|
- spec/lib/billy/handlers/handler_spec.rb
|
@@ -421,6 +423,7 @@ test_files:
|
|
421
423
|
- spec/features/examples/post_api_spec.rb
|
422
424
|
- spec/features/examples/preflight_request_spec.rb
|
423
425
|
- spec/features/examples/tumblr_api_spec.rb
|
426
|
+
- spec/lib/billy/browsers/capybara_spec.rb
|
424
427
|
- spec/lib/billy/cache_spec.rb
|
425
428
|
- spec/lib/billy/handlers/cache_handler_spec.rb
|
426
429
|
- spec/lib/billy/handlers/handler_spec.rb
|