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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 6445deb6e30f295a1f15a5f4b1a094be474a587b375ecc6f23023baf0c74a9a0
4
- data.tar.gz: b1da2a249c2d37d679f4134714ee1c33f6f6eb77fabefdb34637d1ebdf88b655
3
+ metadata.gz: 9abe93dc66216bc06e928bc9b61d92c52aaa718c196664afbaece19ef9dedd06
4
+ data.tar.gz: 76967de33848f166cc247c0a20ac917537331293237e33d8a5693fd1756221ba
5
5
  SHA512:
6
- metadata.gz: fde48ead48a81d1f6b98e307aac098f3fd5357629a147fda05800120708e86f51a78433d15266e559ac856d22dd99f931e7a6c3a3ae10e158eb786b9d095381b
7
- data.tar.gz: d4e2312af4c9a8e67c5d7316b0c9a0384d451974a78b3c9b3077d5392a492710460df32c08e4767a17f3e9e6f883e6ce98a9b81168e2e6dced1250ba6204104a
6
+ metadata.gz: 234b170df43cc3954a49e7fdae65593b1de7e07b0ae4fc3e68dfc9da620c348d700af14f533d379448f1da764cd484f2e07752b2254d59c602b76d96ebb14449
7
+ data.tar.gz: 21e5760521c6c6d74d9a969834cc1856f780f98350665793a3028140f8b2f738a4df6060a2d8043946d977b6f504c74625df12a763fc7e8b29619f9aba7c8423
@@ -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(:text => "I'm not Google!")
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(: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')
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(:redirect_to => 'http://example.com/other')
99
- proxy.stub('http://example.com/missing/').and_return(:code => 404, :body => 'Not found')
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(:text => 'secrets!!1!')
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
- :code => 200,
115
- :text => "Hello, #{params['name'][0]}"
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 => 'all').and_return(Proc.new { |*args|
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', :method => 'post').and_return(
135
- :headers => { 'Access-Control-Allow-Origin' => '*' },
136
- :code => 201
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', :method => :options).and_return(
141
- :headers => {
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
- :code => 200
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(:text => 'Foobar')
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(:text => "I'm not Google!")
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(:text => "I'm not Google!")
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']
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Billy
2
- VERSION = '2.2.0'
2
+ VERSION = '2.3.0'
3
3
  end
@@ -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)
@@ -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.2.0
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-10-27 00:00:00.000000000 Z
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