puffing-billy 0.3.0 → 0.4.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/CHANGELOG.md +6 -0
- data/Gemfile.lock +5 -4
- data/README.md +7 -0
- data/lib/billy.rb +2 -1
- data/lib/billy/cache.rb +19 -5
- data/lib/billy/config.rb +2 -1
- data/lib/billy/version.rb +1 -1
- data/puffing-billy.gemspec +2 -1
- data/spec/lib/billy/cache_spec.rb +38 -0
- metadata +30 -16
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 17920d6438879d1d259e39e392c06bd47b42fce5
|
4
|
+
data.tar.gz: c9637100ed8fe09ac260dc2c29fe3047975e9a69
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4eb515c5510665d687778a9672ab955fade8c6fb2c4970056e6122c8688b01755c910e675929588c519b77a9f41ca4f799e0de33e6c5eb0656a286f52aa255ae
|
7
|
+
data.tar.gz: b33a22eb955333f85094a73ffeaf7a59416bdef8b87686815d50329e15619ba70c9dd3bbfe913f47a7805c830bab4f85d266a5d66eaa7845763683ca7d223a55
|
data/CHANGELOG.md
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,8 +1,8 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
puffing-billy (0.
|
5
|
-
|
4
|
+
puffing-billy (0.4.0)
|
5
|
+
addressable
|
6
6
|
em-http-request
|
7
7
|
em-synchrony
|
8
8
|
eventmachine
|
@@ -13,7 +13,7 @@ PATH
|
|
13
13
|
GEM
|
14
14
|
remote: https://rubygems.org/
|
15
15
|
specs:
|
16
|
-
addressable (2.3.
|
16
|
+
addressable (2.3.6)
|
17
17
|
builder (3.2.2)
|
18
18
|
capybara (2.1.0)
|
19
19
|
mime-types (>= 1.16)
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
ffi (~> 1.0, >= 1.0.11)
|
31
31
|
cliver (0.3.2)
|
32
32
|
coderay (1.1.0)
|
33
|
-
cookiejar (0.3.
|
33
|
+
cookiejar (0.3.2)
|
34
34
|
cucumber (1.3.10)
|
35
35
|
builder (>= 2.1.2)
|
36
36
|
diff-lcs (>= 1.1.3)
|
@@ -123,6 +123,7 @@ PLATFORMS
|
|
123
123
|
ruby
|
124
124
|
|
125
125
|
DEPENDENCIES
|
126
|
+
capybara
|
126
127
|
capybara-webkit (~> 1.0)
|
127
128
|
cucumber
|
128
129
|
faraday
|
data/README.md
CHANGED
@@ -180,6 +180,7 @@ Billy.configure do |c|
|
|
180
180
|
"https://www.facebook.com/dialog/oauth",
|
181
181
|
"http://cdn.api.twitter.com/1/urls/count.json"]
|
182
182
|
c.path_blacklist = []
|
183
|
+
c.merge_cached_responses_whitelist = []
|
183
184
|
c.persist_cache = true
|
184
185
|
c.ignore_cache_port = true # defaults to true
|
185
186
|
c.non_successful_cache_disabled = false
|
@@ -218,6 +219,12 @@ including whitelisted ones. This is useful if your AUT has routes that get data
|
|
218
219
|
from external services, such as `/api` where the ajax request is a local URL but
|
219
220
|
the actual data is coming from a different application that you want to cache.
|
220
221
|
|
222
|
+
`c.merge_cached_responses_whitelist = []` is used to group together the cached
|
223
|
+
responses for specific uri regexes that match any part of the url. This is useful
|
224
|
+
for ensuring that any kind of analytics and various social buttons that have
|
225
|
+
slightly different urls each time can be recorded once and reused nicely. Note
|
226
|
+
that the request body is ignored for requests that contain a body.
|
227
|
+
|
221
228
|
`c.ignore_cache_port` is used to strip the port from the URL if it exists. This
|
222
229
|
is useful when caching local paths (via `path_blacklist`) or other local rack apps
|
223
230
|
that are running on random ports.
|
data/lib/billy.rb
CHANGED
@@ -43,9 +43,9 @@ module Billy
|
|
43
43
|
if defined?(Capybara::Webkit::Driver)
|
44
44
|
Capybara.register_driver :webkit_billy do |app|
|
45
45
|
driver = Capybara::Webkit::Driver.new(app)
|
46
|
+
driver.browser.ignore_ssl_errors
|
46
47
|
driver.browser.set_proxy(:host => Billy.proxy.host,
|
47
48
|
:port => Billy.proxy.port)
|
48
|
-
driver.browser.ignore_ssl_errors
|
49
49
|
driver
|
50
50
|
end
|
51
51
|
end
|
@@ -53,6 +53,7 @@ module Billy
|
|
53
53
|
if defined?(Selenium::WebDriver)
|
54
54
|
Capybara.register_driver :selenium_billy do |app|
|
55
55
|
profile = Selenium::WebDriver::Firefox::Profile.new
|
56
|
+
profile.assume_untrusted_certificate_issuer = false
|
56
57
|
profile.proxy = Selenium::WebDriver::Proxy.new(
|
57
58
|
:http => "#{Billy.proxy.host}:#{Billy.proxy.port}",
|
58
59
|
:ssl => "#{Billy.proxy.host}:#{Billy.proxy.port}")
|
data/lib/billy/cache.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'resolv'
|
2
|
-
require 'uri'
|
2
|
+
require 'addressable/uri'
|
3
3
|
require 'yaml'
|
4
4
|
require 'billy/json_utils'
|
5
5
|
require 'singleton'
|
@@ -72,11 +72,16 @@ module Billy
|
|
72
72
|
|
73
73
|
def key(method, orig_url, body, log_key = false)
|
74
74
|
ignore_params = Billy.config.ignore_params.include?(format_url(orig_url, true))
|
75
|
-
|
76
|
-
|
75
|
+
merge_cached_response_key = _merge_cached_response_key(orig_url)
|
76
|
+
url = Addressable::URI.parse(format_url(orig_url, ignore_params))
|
77
|
+
key = if merge_cached_response_key
|
78
|
+
method+'_'+Digest::SHA1.hexdigest(scope.to_s + merge_cached_response_key)
|
79
|
+
else
|
80
|
+
method+'_'+url.host+'_'+Digest::SHA1.hexdigest(scope.to_s + url.to_s)
|
81
|
+
end
|
77
82
|
body_msg = ''
|
78
83
|
|
79
|
-
if method == 'post'
|
84
|
+
if method == 'post' && !ignore_params && !merge_cached_response_key
|
80
85
|
body_formatted = JSONUtils::json?(body.to_s) ? JSONUtils::sort_json(body.to_s) : body.to_s
|
81
86
|
body_msg = " with body '#{body_formatted}'"
|
82
87
|
key += '_'+Digest::SHA1.hexdigest(body_formatted)
|
@@ -87,7 +92,7 @@ module Billy
|
|
87
92
|
end
|
88
93
|
|
89
94
|
def format_url(url, ignore_params=false, dynamic_jsonp=Billy.config.dynamic_jsonp)
|
90
|
-
url = URI(url)
|
95
|
+
url = Addressable::URI.parse(url)
|
91
96
|
port_to_include = Billy.config.ignore_cache_port ? '' : ":#{url.port}"
|
92
97
|
formatted_url = url.scheme+'://'+url.host+port_to_include+url.path
|
93
98
|
|
@@ -133,6 +138,15 @@ module Billy
|
|
133
138
|
|
134
139
|
private
|
135
140
|
|
141
|
+
def _merge_cached_response_key(url)
|
142
|
+
Billy.config.merge_cached_responses_whitelist.each do |disable_regex|
|
143
|
+
if url =~ disable_regex
|
144
|
+
return disable_regex.to_s # Use the stringified regex as the cache key if it matches
|
145
|
+
end
|
146
|
+
end
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
|
136
150
|
attr_writer :scope
|
137
151
|
end
|
138
152
|
end
|
data/lib/billy/config.rb
CHANGED
@@ -9,7 +9,7 @@ module Billy
|
|
9
9
|
attr_accessor :logger, :cache, :cache_request_headers, :whitelist, :path_blacklist, :ignore_params,
|
10
10
|
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
|
11
11
|
:non_whitelisted_requests_disabled, :cache_path, :proxy_port, :proxied_request_inactivity_timeout,
|
12
|
-
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys
|
12
|
+
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :merge_cached_responses_whitelist
|
13
13
|
|
14
14
|
def initialize
|
15
15
|
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
|
@@ -21,6 +21,7 @@ module Billy
|
|
21
21
|
@cache_request_headers = false
|
22
22
|
@whitelist = DEFAULT_WHITELIST
|
23
23
|
@path_blacklist = []
|
24
|
+
@merge_cached_responses_whitelist = []
|
24
25
|
@ignore_params = []
|
25
26
|
@persist_cache = false
|
26
27
|
@dynamic_jsonp = false
|
data/lib/billy/version.rb
CHANGED
data/puffing-billy.gemspec
CHANGED
@@ -20,17 +20,18 @@ Gem::Specification.new do |gem|
|
|
20
20
|
gem.add_development_dependency "faraday"
|
21
21
|
gem.add_development_dependency "poltergeist"
|
22
22
|
gem.add_development_dependency "selenium-webdriver"
|
23
|
+
gem.add_development_dependency "capybara"
|
23
24
|
gem.add_development_dependency "capybara-webkit", "~> 1.0"
|
24
25
|
gem.add_development_dependency "rack"
|
25
26
|
gem.add_development_dependency "guard"
|
26
27
|
gem.add_development_dependency "rb-inotify"
|
27
28
|
gem.add_development_dependency "pry"
|
28
29
|
gem.add_development_dependency "cucumber"
|
30
|
+
gem.add_runtime_dependency "addressable"
|
29
31
|
gem.add_runtime_dependency "eventmachine"
|
30
32
|
gem.add_runtime_dependency "em-synchrony"
|
31
33
|
gem.add_runtime_dependency "em-http-request"
|
32
34
|
gem.add_runtime_dependency "eventmachine_httpserver"
|
33
35
|
gem.add_runtime_dependency "http_parser.rb", "~> 0.6.0"
|
34
36
|
gem.add_runtime_dependency "multi_json"
|
35
|
-
gem.add_runtime_dependency "capybara"
|
36
37
|
end
|
@@ -7,6 +7,7 @@ describe Billy::Cache do
|
|
7
7
|
let(:callback) { '&callback=quux' }
|
8
8
|
let(:fragment) { '#baz' }
|
9
9
|
let(:base_url) { 'http://example.com' }
|
10
|
+
let(:pipe_url) { 'https://fonts.googleapis.com:443/css?family=Cabin+Sketch:400,700|Love+Ya+Like+A+Sister' }
|
10
11
|
let(:fragment_url) { "#{base_url}/#{fragment}" }
|
11
12
|
let(:params_url) { "#{base_url}#{params}" }
|
12
13
|
let(:params_url_with_callback) { "#{base_url}#{params}#{callback}" }
|
@@ -22,6 +23,10 @@ describe Billy::Cache do
|
|
22
23
|
it 'appends params and fragment if both are present' do
|
23
24
|
expect(cache.format_url(params_fragment_url)).to eq params_fragment_url
|
24
25
|
end
|
26
|
+
it 'does not raise error for URLs with pipes' do
|
27
|
+
expect { cache.format_url(pipe_url) }.not_to raise_error
|
28
|
+
end
|
29
|
+
|
25
30
|
context "when dynamic_jsonp is true" do
|
26
31
|
it 'omits the callback param by default' do
|
27
32
|
expect(cache.format_url(params_url_with_callback, false, true)).to eq params_url
|
@@ -50,5 +55,38 @@ describe Billy::Cache do
|
|
50
55
|
expect(cache.format_url(params_fragment_url, true)).to eq base_url
|
51
56
|
end
|
52
57
|
end
|
58
|
+
|
59
|
+
context "with merge_cached_responses_whitelist set" do
|
60
|
+
|
61
|
+
let(:analytics_url1) { "http://www.example-analytics.com/user/SDF879932/" }
|
62
|
+
let(:analytics_url2) { "http://www.example-analytics.com/user/OIWEMLW39/" }
|
63
|
+
let(:regular_url) { "http://www.example-analytics.com/user.js" }
|
64
|
+
|
65
|
+
let(:regex_to_match_analytics_urls_only) do
|
66
|
+
# Note that it matches the forward slash at the end of the URL, which doesn't match regular_url:
|
67
|
+
/www\.example\-analytics\.com\/user\//
|
68
|
+
end
|
69
|
+
|
70
|
+
before do
|
71
|
+
allow(Billy.config).to receive(:merge_cached_responses_whitelist) {
|
72
|
+
[regex_to_match_analytics_urls_only]
|
73
|
+
}
|
74
|
+
end
|
75
|
+
|
76
|
+
it "has one cache key for the two analytics urls that match, and a separate one for the other that doesn't" do
|
77
|
+
expect(cache.key("post", analytics_url1, "body")).to eq cache.key("post", analytics_url2, "body")
|
78
|
+
expect(cache.key("post", analytics_url1, "body")).not_to eq cache.key("post", regular_url, "body")
|
79
|
+
end
|
80
|
+
|
81
|
+
it "More specifically, the cache keys should be identical for the 2 analytics urls" do
|
82
|
+
identical_cache_key = "post_5fcb7a450e4cd54dcffcb526212757ee0ca9dc17"
|
83
|
+
distinct_cache_key = "post_www.example-analytics.com_81f097654a523bd7ddb10fd4aee781723e076a1a_02083f4579e08a612425c0c1a17ee47add783b94"
|
84
|
+
|
85
|
+
expect(cache.key("post", analytics_url1, "body")).to eq identical_cache_key
|
86
|
+
expect(cache.key("post", regular_url, "body")).to eq distinct_cache_key
|
87
|
+
expect(cache.key("post", analytics_url2, "body")).to eq identical_cache_key
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
53
91
|
end
|
54
92
|
end
|
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: 0.
|
4
|
+
version: 0.4.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:
|
11
|
+
date: 2015-01-02 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ">="
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: capybara
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
83
97
|
- !ruby/object:Gem::Dependency
|
84
98
|
name: capybara-webkit
|
85
99
|
requirement: !ruby/object:Gem::Requirement
|
@@ -164,6 +178,20 @@ dependencies:
|
|
164
178
|
- - ">="
|
165
179
|
- !ruby/object:Gem::Version
|
166
180
|
version: '0'
|
181
|
+
- !ruby/object:Gem::Dependency
|
182
|
+
name: addressable
|
183
|
+
requirement: !ruby/object:Gem::Requirement
|
184
|
+
requirements:
|
185
|
+
- - ">="
|
186
|
+
- !ruby/object:Gem::Version
|
187
|
+
version: '0'
|
188
|
+
type: :runtime
|
189
|
+
prerelease: false
|
190
|
+
version_requirements: !ruby/object:Gem::Requirement
|
191
|
+
requirements:
|
192
|
+
- - ">="
|
193
|
+
- !ruby/object:Gem::Version
|
194
|
+
version: '0'
|
167
195
|
- !ruby/object:Gem::Dependency
|
168
196
|
name: eventmachine
|
169
197
|
requirement: !ruby/object:Gem::Requirement
|
@@ -248,20 +276,6 @@ dependencies:
|
|
248
276
|
- - ">="
|
249
277
|
- !ruby/object:Gem::Version
|
250
278
|
version: '0'
|
251
|
-
- !ruby/object:Gem::Dependency
|
252
|
-
name: capybara
|
253
|
-
requirement: !ruby/object:Gem::Requirement
|
254
|
-
requirements:
|
255
|
-
- - ">="
|
256
|
-
- !ruby/object:Gem::Version
|
257
|
-
version: '0'
|
258
|
-
type: :runtime
|
259
|
-
prerelease: false
|
260
|
-
version_requirements: !ruby/object:Gem::Requirement
|
261
|
-
requirements:
|
262
|
-
- - ">="
|
263
|
-
- !ruby/object:Gem::Version
|
264
|
-
version: '0'
|
265
279
|
description: A stubbing proxy server for ruby. Connect it to your browser in integration
|
266
280
|
tests to fake interactions with remote HTTP(S) servers.
|
267
281
|
email:
|