puffing-billy 0.2.3 → 0.3.0
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/.gitignore +1 -0
- data/.travis.yml +6 -0
- data/CHANGELOG.md +65 -0
- data/Gemfile.lock +6 -3
- data/README.md +43 -3
- data/lib/billy.rb +5 -0
- data/lib/billy/cache.rb +21 -5
- data/lib/billy/config.rb +8 -1
- data/lib/billy/handlers/cache_handler.rb +51 -0
- data/lib/billy/handlers/handler.rb +45 -0
- data/lib/billy/handlers/proxy_handler.rb +112 -0
- data/lib/billy/handlers/request_handler.rb +59 -0
- data/lib/billy/handlers/stub_handler.rb +48 -0
- data/lib/billy/proxy.rb +11 -36
- data/lib/billy/proxy_connection.rb +18 -140
- data/lib/billy/version.rb +1 -1
- data/puffing-billy.gemspec +2 -1
- data/spec/features/examples/facebook_api_spec.rb +2 -3
- data/spec/features/examples/tumblr_api_spec.rb +1 -1
- data/spec/lib/billy/cache_spec.rb +18 -1
- data/spec/lib/billy/handlers/cache_handler_spec.rb +124 -0
- data/spec/lib/billy/handlers/handler_spec.rb +16 -0
- data/spec/lib/billy/handlers/proxy_handler_spec.rb +171 -0
- data/spec/lib/billy/handlers/request_handler_spec.rb +144 -0
- data/spec/lib/billy/handlers/stub_handler_spec.rb +71 -0
- data/spec/lib/billy/resource_utils_spec.rb +3 -3
- data/spec/lib/proxy_spec.rb +15 -8
- data/spec/spec_helper.rb +1 -1
- metadata +37 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 30ec3de1e00ab91373eb88106e301a8fe9963701
|
4
|
+
data.tar.gz: 7300cdd6f73ae4e5a5a6e6a1dd6108cb9074d272
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1e00330461d05f7fa3e3f01cad76e35e152f2ffc44c7b3633d0b780c60e714429185b7200897eaef6c0d96e7067a78cb1cd63e680013601f9f873f3e0f58eeff
|
7
|
+
data.tar.gz: 6d1099b167707b5c41f38444f81ff39c6d6a1753e8072fdbbca85c2e2a605c391591ebf095bff3b6173e4a7060304b0c30c52e1a92723f0c502bb7a4a78bf036
|
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/CHANGELOG.md
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
v0.3.0, 2014-12-29
|
2
|
+
------------------
|
3
|
+
|
4
|
+
* Fixing a bug where proxy to SSL can duplicate https in the request_url (#36)
|
5
|
+
* Refactor proxy responses (#37)
|
6
|
+
* Update http_parser to 0.6.0 and remove CONNECT request hack (#38)
|
7
|
+
* Allow configurable Billy proxy port (#40)
|
8
|
+
* Refactor handlers (#41)
|
9
|
+
* Mark step definitions as ruby code (#52)
|
10
|
+
* Adds EventMachine timeout configuration (#57)
|
11
|
+
* Support dynamic jsonp with params (#58)
|
12
|
+
* Writing error messages to the logger rather than stdout (#69)
|
13
|
+
* Don't recommend changing javascript_driver config (#70)
|
14
|
+
* README link pointing at wrong target (#73)
|
15
|
+
* Adding example config to README for playing nicely with Webmock, VCR (#74)
|
16
|
+
* Make dynamic_jsonp regex less brittle (#81)
|
17
|
+
|
18
|
+
v0.2.3, 2014-02-07
|
19
|
+
------------------
|
20
|
+
|
21
|
+
* Fixed facebook spec (#24)
|
22
|
+
* Check for existing persistent cache files on demand (#26)
|
23
|
+
* Lazy-loading proxy and other minor fixes (#28)
|
24
|
+
* Support service-oriented architectures, scope cache to scenarios, and sort JSON in POSTs to avoid duplicate cache files (#30)
|
25
|
+
* Set the minimum version of capybara-webkit to 1.0.0 (#31)
|
26
|
+
* Updated gems, cache request headers, handle non-successful responses, ability to stop new connections (#33)
|
27
|
+
* Add requires matching gem name (#34)
|
28
|
+
* Remove duplicated rspec devel dependency (#35)
|
29
|
+
|
30
|
+
v0.2.1, 2013-05-12
|
31
|
+
------------------
|
32
|
+
|
33
|
+
* Add cucumber documentation to readme. (#12)
|
34
|
+
* Use multi_json (#13)
|
35
|
+
* Remove require from Gemfile example (#14)
|
36
|
+
* Add a README example of returning headers (#16)
|
37
|
+
|
38
|
+
v0.2.0, 2013-03-17
|
39
|
+
------------------
|
40
|
+
|
41
|
+
* Update README with HTTPS quirk and trailing slash behaviour. (#3)
|
42
|
+
* Fixes to work with Capybara-Webkit (#6)
|
43
|
+
* VCR-like cache (#7)
|
44
|
+
|
45
|
+
v0.1.3, 2012-11-05
|
46
|
+
------------------
|
47
|
+
|
48
|
+
* Implemented caching
|
49
|
+
|
50
|
+
v0.1.2, 2012-10-12
|
51
|
+
------------------
|
52
|
+
|
53
|
+
* Slightly saner driver setup
|
54
|
+
* Updated README
|
55
|
+
|
56
|
+
v0.1.1, 2012-10-12
|
57
|
+
------------------
|
58
|
+
|
59
|
+
* Content encoding fixes
|
60
|
+
* Updated README
|
61
|
+
|
62
|
+
v0.1.0, 2012-10-11
|
63
|
+
------------------
|
64
|
+
|
65
|
+
* Initial release
|
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
puffing-billy (0.
|
4
|
+
puffing-billy (0.3.0)
|
5
5
|
capybara
|
6
6
|
em-http-request
|
7
|
+
em-synchrony
|
7
8
|
eventmachine
|
8
9
|
eventmachine_httpserver
|
9
|
-
http_parser.rb
|
10
|
+
http_parser.rb (~> 0.6.0)
|
10
11
|
multi_json
|
11
12
|
|
12
13
|
GEM
|
@@ -29,7 +30,7 @@ GEM
|
|
29
30
|
ffi (~> 1.0, >= 1.0.11)
|
30
31
|
cliver (0.3.2)
|
31
32
|
coderay (1.1.0)
|
32
|
-
cookiejar (0.3.
|
33
|
+
cookiejar (0.3.1)
|
33
34
|
cucumber (1.3.10)
|
34
35
|
builder (>= 2.1.2)
|
35
36
|
diff-lcs (>= 1.1.3)
|
@@ -46,6 +47,8 @@ GEM
|
|
46
47
|
http_parser.rb (>= 0.6.0)
|
47
48
|
em-socksify (0.3.0)
|
48
49
|
eventmachine (>= 1.0.0.beta.4)
|
50
|
+
em-synchrony (1.0.3)
|
51
|
+
eventmachine (>= 1.0.0.beta.1)
|
49
52
|
eventmachine (1.0.3)
|
50
53
|
eventmachine_httpserver (0.2.1)
|
51
54
|
faraday (0.9.0)
|
data/README.md
CHANGED
@@ -120,10 +120,9 @@ Feature: Stubbing via billy
|
|
120
120
|
|
121
121
|
And in steps:
|
122
122
|
|
123
|
-
```
|
123
|
+
```ruby
|
124
124
|
Before('@billy') do
|
125
125
|
Capybara.current_driver = :poltergeist_billy
|
126
|
-
Capybara.javascript_driver = :poltergeist_billy
|
127
126
|
end
|
128
127
|
|
129
128
|
And /^a stub for google$/ do
|
@@ -202,6 +201,18 @@ caching. You should mostly use this for analytics and various social buttons as
|
|
202
201
|
they use cache avoidance techniques, but return practically the same response
|
203
202
|
that most often does not affect your test results.
|
204
203
|
|
204
|
+
`c.dynamic_jsonp` is used to rewrite the body of JSONP responses based on the
|
205
|
+
callback parameter. For example, if a request to `http://example.com/foo?callback=bar`
|
206
|
+
returns `bar({"some": "json"});` and is recorded, then a later request to
|
207
|
+
`http://example.com/foo?callback=baz` will be a cache hit and respond with
|
208
|
+
`baz({"some": "json"});` This is useful because most JSONP implementations
|
209
|
+
base the callback name off of a timestamp or something else dynamic.
|
210
|
+
|
211
|
+
`c.dynamic_jsonp_keys` is used to configure which parameters to ignore when
|
212
|
+
using `c.dynamic_jsonp`. This is helpful when JSONP APIs use cache-busting
|
213
|
+
parameters. For example, if you want `http://example.com/foo?callback=bar&id=1&cache_bust=12345` and `http://example.com/foo?callback=baz&id=1&cache_bust=98765` to be cache hits for each other, you would set `c.dynamic_jsonp_keys = ['callback', 'cache_bust']` to ignore both params. Note
|
214
|
+
that in this example the `id` param would still be considered important.
|
215
|
+
|
205
216
|
`c.path_blacklist = []` is used to always cache specific paths on any hostnames,
|
206
217
|
including whitelisted ones. This is useful if your AUT has routes that get data
|
207
218
|
from external services, such as `/api` where the ajax request is a local URL but
|
@@ -287,13 +298,42 @@ RSpec.configure do |config|
|
|
287
298
|
end
|
288
299
|
```
|
289
300
|
|
301
|
+
## Proxy timeouts
|
302
|
+
|
303
|
+
By default, the Puffing Billy proxy will use the EventMachine:HttpRequest timeouts of 5 seconds
|
304
|
+
for connect and 10 seconds for inactivity when talking to downstream servers.
|
305
|
+
|
306
|
+
These can be configured as follows:
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
Billy.configure do |c|
|
310
|
+
c.proxied_request_connect_timeout = 20
|
311
|
+
c.proxied_request_inactivity_timeout = 20
|
312
|
+
end
|
313
|
+
```
|
314
|
+
|
290
315
|
## Customising the javascript driver
|
291
316
|
|
292
317
|
If you use a customised Capybara driver, remember to set the proxy address
|
293
318
|
and tell it to ignore SSL certificate warnings. See
|
294
|
-
[lib/billy
|
319
|
+
[lib/billy.rb](https://github.com/oesmith/puffing-billy/blob/master/lib/billy.rb)
|
295
320
|
to see how Billy's default drivers are configured.
|
296
321
|
|
322
|
+
## Working with VCR and Webmock
|
323
|
+
If you use VCR and Webmock elsewhere in your specs, you will need to disable them
|
324
|
+
for your specs utilizing Puffing Billy. To do so, you can configure your `spec_helper.rb`
|
325
|
+
as shown below:
|
326
|
+
|
327
|
+
```ruby
|
328
|
+
RSpec.configure do |config|
|
329
|
+
config.around(:each, type: :feature) do |example|
|
330
|
+
WebMock.allow_net_connect!
|
331
|
+
VCR.turned_off { example.run }
|
332
|
+
WebMock.disable_net_connect!
|
333
|
+
end
|
334
|
+
end
|
335
|
+
```
|
336
|
+
|
297
337
|
## FAQ
|
298
338
|
|
299
339
|
1. Why name it after a train?
|
data/lib/billy.rb
CHANGED
@@ -1,5 +1,10 @@
|
|
1
1
|
require "billy/version"
|
2
2
|
require "billy/config"
|
3
|
+
require "billy/handlers/handler"
|
4
|
+
require "billy/handlers/request_handler"
|
5
|
+
require "billy/handlers/stub_handler"
|
6
|
+
require "billy/handlers/proxy_handler"
|
7
|
+
require "billy/handlers/cache_handler"
|
3
8
|
require "billy/proxy_request_stub"
|
4
9
|
require "billy/cache"
|
5
10
|
require "billy/proxy"
|
data/lib/billy/cache.rb
CHANGED
@@ -2,9 +2,12 @@ require 'resolv'
|
|
2
2
|
require 'uri'
|
3
3
|
require 'yaml'
|
4
4
|
require 'billy/json_utils'
|
5
|
+
require 'singleton'
|
5
6
|
|
6
7
|
module Billy
|
7
8
|
class Cache
|
9
|
+
include Singleton
|
10
|
+
|
8
11
|
attr_reader :scope
|
9
12
|
|
10
13
|
def initialize
|
@@ -30,7 +33,7 @@ module Billy
|
|
30
33
|
begin
|
31
34
|
@cache[key] = YAML.load(File.open(cache_file(key))) if persisted?(key)
|
32
35
|
rescue ArgumentError => e
|
33
|
-
|
36
|
+
Billy.log :error, "Could not parse YAML: #{e.message}"
|
34
37
|
nil
|
35
38
|
end
|
36
39
|
end
|
@@ -83,14 +86,27 @@ module Billy
|
|
83
86
|
key
|
84
87
|
end
|
85
88
|
|
86
|
-
def format_url(url, ignore_params=false)
|
89
|
+
def format_url(url, ignore_params=false, dynamic_jsonp=Billy.config.dynamic_jsonp)
|
87
90
|
url = URI(url)
|
88
91
|
port_to_include = Billy.config.ignore_cache_port ? '' : ":#{url.port}"
|
89
92
|
formatted_url = url.scheme+'://'+url.host+port_to_include+url.path
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
+
|
94
|
+
return formatted_url if ignore_params
|
95
|
+
|
96
|
+
if url.query
|
97
|
+
query_string = if dynamic_jsonp
|
98
|
+
query_hash = Rack::Utils.parse_query(url.query)
|
99
|
+
Billy.config.dynamic_jsonp_keys.each{|k| query_hash.delete(k) }
|
100
|
+
Rack::Utils.build_query(query_hash)
|
101
|
+
else
|
102
|
+
url.query
|
103
|
+
end
|
104
|
+
|
105
|
+
formatted_url += "?#{query_string}"
|
93
106
|
end
|
107
|
+
|
108
|
+
formatted_url += '#'+url.fragment if url.fragment
|
109
|
+
|
94
110
|
formatted_url
|
95
111
|
end
|
96
112
|
|
data/lib/billy/config.rb
CHANGED
@@ -4,10 +4,12 @@ require 'tmpdir'
|
|
4
4
|
module Billy
|
5
5
|
class Config
|
6
6
|
DEFAULT_WHITELIST = ['127.0.0.1', 'localhost']
|
7
|
+
RANDOM_AVAILABLE_PORT = 0 # https://github.com/eventmachine/eventmachine/wiki/FAQ#wiki-can-i-start-a-server-on-a-random-available-port
|
7
8
|
|
8
9
|
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :path_blacklist, :ignore_params,
|
9
10
|
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
|
10
|
-
:non_whitelisted_requests_disabled, :cache_path
|
11
|
+
:non_whitelisted_requests_disabled, :cache_path, :proxy_port, :proxied_request_inactivity_timeout,
|
12
|
+
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys
|
11
13
|
|
12
14
|
def initialize
|
13
15
|
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
@@ -21,11 +23,16 @@ module Billy
|
|
21
23
|
@path_blacklist = []
|
22
24
|
@ignore_params = []
|
23
25
|
@persist_cache = false
|
26
|
+
@dynamic_jsonp = false
|
27
|
+
@dynamic_jsonp_keys = ["callback"]
|
24
28
|
@ignore_cache_port = true
|
25
29
|
@non_successful_cache_disabled = false
|
26
30
|
@non_successful_error_level = :warn
|
27
31
|
@non_whitelisted_requests_disabled = false
|
28
32
|
@cache_path = File.join(Dir.tmpdir, 'puffing-billy')
|
33
|
+
@proxy_port = RANDOM_AVAILABLE_PORT
|
34
|
+
@proxied_request_inactivity_timeout = 10 # defaults from https://github.com/igrigorik/em-http-request/wiki/Redirects-and-Timeouts
|
35
|
+
@proxied_request_connect_timeout = 5
|
29
36
|
end
|
30
37
|
end
|
31
38
|
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'billy/handlers/handler'
|
2
|
+
require 'cgi'
|
3
|
+
|
4
|
+
module Billy
|
5
|
+
class CacheHandler
|
6
|
+
extend Forwardable
|
7
|
+
include Handler
|
8
|
+
|
9
|
+
def_delegators :cache, :reset, :cached?
|
10
|
+
|
11
|
+
def initialize
|
12
|
+
@cache = Billy::Cache.instance
|
13
|
+
end
|
14
|
+
|
15
|
+
def handle_request(method, url, headers, body)
|
16
|
+
method = method.downcase
|
17
|
+
if handles_request?(method, url, headers, body)
|
18
|
+
if (response = cache.fetch(method, url, body))
|
19
|
+
Billy.log(:info, "puffing-billy: CACHE #{method} for '#{url}'")
|
20
|
+
|
21
|
+
if Billy.config.dynamic_jsonp
|
22
|
+
replace_response_callback(response, url)
|
23
|
+
end
|
24
|
+
|
25
|
+
return response
|
26
|
+
end
|
27
|
+
end
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
|
31
|
+
def handles_request?(method, url, headers, body)
|
32
|
+
cached?(method, url, body)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def replace_response_callback(response, url)
|
38
|
+
request_uri = URI::parse(url)
|
39
|
+
if request_uri.query
|
40
|
+
params = CGI::parse(request_uri.query)
|
41
|
+
if params['callback'].any? and response[:content].match(/\w+\(/)
|
42
|
+
response[:content].sub!(/\w+\(/, params['callback'].first + '(')
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def cache
|
48
|
+
@cache
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Billy
|
2
|
+
module Handler
|
3
|
+
##
|
4
|
+
#
|
5
|
+
# Handles an incoming HTTP request and returns a response.
|
6
|
+
#
|
7
|
+
# This method accepts HTTP request parameters and must return
|
8
|
+
# a response hash containing the keys :status, :headers,
|
9
|
+
# and :content, or nil if the request cannot be fulfilled.
|
10
|
+
#
|
11
|
+
# @param [String] http_method The HTTP method used, e.g. 'http' or 'https'
|
12
|
+
# @param [String] url The URL requested.
|
13
|
+
# @param [String] headers The headers of the HTTP request.
|
14
|
+
# @param [String] body The body of the HTTP request.
|
15
|
+
# @return [Hash] A hash with the keys [:status, :headers, :content]
|
16
|
+
# Returns {:error => "Some error message"} if a failure occurs.
|
17
|
+
# Returns nil if the request cannot be fulfilled.
|
18
|
+
def handle_request(http_method, url, headers, body)
|
19
|
+
{ error: 'The handler has not overridden the handle_request method!' }
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
#
|
24
|
+
# Checks if the Handler can respond to the given request.
|
25
|
+
#
|
26
|
+
# @param [String] http_method The HTTP method used, e.g. 'http' or 'https'
|
27
|
+
# @param [String] url The URL requested.
|
28
|
+
# @param [String] headers The headers of the HTTP request.
|
29
|
+
# @param [String] body The body of the HTTP request.
|
30
|
+
# @return [Boolean] True if the Handler can respond to the request, else false.
|
31
|
+
#
|
32
|
+
def handles_request?(http_method, url, headers, body)
|
33
|
+
false
|
34
|
+
end
|
35
|
+
|
36
|
+
##
|
37
|
+
#
|
38
|
+
# Resets the Handler to the default/new state
|
39
|
+
#
|
40
|
+
# This allows the handler to be set back to its default state
|
41
|
+
# at the end of tests or whenever else necessary.
|
42
|
+
#
|
43
|
+
def reset; end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require 'billy/handlers/handler'
|
2
|
+
require 'eventmachine'
|
3
|
+
require 'em-synchrony/em-http'
|
4
|
+
|
5
|
+
module Billy
|
6
|
+
class ProxyHandler
|
7
|
+
include Handler
|
8
|
+
|
9
|
+
def handles_request?(method, url, headers, body)
|
10
|
+
!disabled_request?(url)
|
11
|
+
end
|
12
|
+
|
13
|
+
def handle_request(method, url, headers, body)
|
14
|
+
if handles_request?(method, url, headers, body)
|
15
|
+
req = EventMachine::HttpRequest.new(url, {
|
16
|
+
:inactivity_timeout => Billy.config.proxied_request_inactivity_timeout,
|
17
|
+
:connect_timeout => Billy.config.proxied_request_connect_timeout})
|
18
|
+
|
19
|
+
req = req.send(method.downcase, build_request_options(headers, body))
|
20
|
+
|
21
|
+
if req.error
|
22
|
+
return { :error => "Request to #{url} failed with error: #{req.error}" }
|
23
|
+
end
|
24
|
+
|
25
|
+
if req.response
|
26
|
+
response = process_response(req)
|
27
|
+
|
28
|
+
unless allowed_response_code?(response[:status])
|
29
|
+
if Billy.config.non_successful_error_level == :error
|
30
|
+
return { :error => "Request failed due to response status #{response[:status]} for '#{url}' which was not allowed." }
|
31
|
+
else
|
32
|
+
Billy.log(:warn, "puffing-billy: Received response status code #{response[:status]} for '#{url}'")
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
if cacheable?(url, response[:headers], response[:status])
|
37
|
+
Billy::Cache.instance.store(method.downcase, url, headers, body, response[:headers], response[:status], response[:content])
|
38
|
+
end
|
39
|
+
|
40
|
+
Billy.log(:info, "puffing-billy: PROXY #{method} succeeded for '#{url}'")
|
41
|
+
return response
|
42
|
+
end
|
43
|
+
end
|
44
|
+
nil
|
45
|
+
end
|
46
|
+
|
47
|
+
private
|
48
|
+
|
49
|
+
def build_request_options(headers, body)
|
50
|
+
headers = Hash[headers.map { |k,v| [k.downcase, v] }]
|
51
|
+
headers.delete('accept-encoding')
|
52
|
+
|
53
|
+
req_opts = {
|
54
|
+
:redirects => 0,
|
55
|
+
:keepalive => false,
|
56
|
+
:head => headers,
|
57
|
+
:ssl => { :verify => false }
|
58
|
+
}
|
59
|
+
req_opts[:body] = body if body
|
60
|
+
req_opts
|
61
|
+
end
|
62
|
+
|
63
|
+
def process_response(req)
|
64
|
+
response = {
|
65
|
+
:status => req.response_header.status,
|
66
|
+
:headers => req.response_header.raw,
|
67
|
+
:content => req.response.force_encoding('BINARY') }
|
68
|
+
response[:headers].merge!('Connection' => 'close')
|
69
|
+
response[:headers].delete('Transfer-Encoding')
|
70
|
+
response
|
71
|
+
end
|
72
|
+
|
73
|
+
def disabled_request?(url)
|
74
|
+
return false unless Billy.config.non_whitelisted_requests_disabled
|
75
|
+
|
76
|
+
uri = URI(url)
|
77
|
+
# In isolated environments, you may want to stop the request from happening
|
78
|
+
# or else you get "getaddrinfo: Name or service not known" errors
|
79
|
+
blacklisted_path?(uri.path) || !whitelisted_url?(uri)
|
80
|
+
end
|
81
|
+
|
82
|
+
def allowed_response_code?(status)
|
83
|
+
successful_status?(status)
|
84
|
+
end
|
85
|
+
|
86
|
+
def cacheable?(url, headers, status)
|
87
|
+
return false unless Billy.config.cache
|
88
|
+
|
89
|
+
url = URI(url)
|
90
|
+
# Cache the responses if they aren't whitelisted host[:port]s but always cache blacklisted paths on any hosts
|
91
|
+
cacheable_status?(status) && (!whitelisted_url?(url) || blacklisted_path?(url.path))
|
92
|
+
end
|
93
|
+
|
94
|
+
def whitelisted_url?(url)
|
95
|
+
!Billy.config.whitelist.index do |v|
|
96
|
+
v =~ /^#{url.host}(?::#{url.port})?$/
|
97
|
+
end.nil?
|
98
|
+
end
|
99
|
+
|
100
|
+
def blacklisted_path?(path)
|
101
|
+
!Billy.config.path_blacklist.index{|bl| path.include?(bl)}.nil?
|
102
|
+
end
|
103
|
+
|
104
|
+
def successful_status?(status)
|
105
|
+
(200..299).include?(status) || status == 304
|
106
|
+
end
|
107
|
+
|
108
|
+
def cacheable_status?(status)
|
109
|
+
Billy.config.non_successful_cache_disabled ? successful_status?(status) : true
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|