Skip to content

Commit

Permalink
Merge pull request #149 from sonjapeterson/cache-handler-callback
Browse files Browse the repository at this point in the history
Add optional after_cache_handles_request callback for manipulating cached responses
  • Loading branch information
ronwsmith committed Jun 2, 2016
2 parents 642ce8b + ab07455 commit 9792d17
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 1 deletion.
19 changes: 19 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,25 @@ server is required to access the internet. Most common in larger companies.

`c.cache_request_body_methods` is used to specify HTTP methods of requests that you would like to cache separately based on the contents of the request body. The default is ['post'].

`c.after_cache_handles_request` is used to configure a callback that can operate on the response after it has been retrieved from the cache but before it is returned. The callback receives the request and response as arguments, with a request object like: `{ method: method, url: url, headers: headers, body: body }`. An example usage would be manipulating the Access-Control-Allow-Origin header so that your test server doesn't always have to run on the same port in order to accept cached responses to CORS requests:

```
Billy.configure do |c|
...
fix_cors_header = proc do |_request, response|
allowed_origins = response[:headers]['Access-Control-Allow-Origin']
if allowed_origins.present?
localhost_port_pattern = %r{(?<=http://127\.0\.0\.1:)(\d+)}
allowed_origins.sub!(
localhost_port_pattern, Capybara.current_session.server.port.to_s
)
end
end
c.after_cache_handles_request = fix_cors_header
...
end
```

### Cache Scopes

If you need to cache different responses to the same HTTP request, you can use
Expand Down
3 changes: 2 additions & 1 deletion lib/billy/config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Config
:persist_cache, :ignore_cache_port, :non_successful_cache_disabled, :non_successful_error_level,
:non_whitelisted_requests_disabled, :cache_path, :proxy_host, :proxy_port, :proxied_request_inactivity_timeout,
:proxied_request_connect_timeout, :dynamic_jsonp, :dynamic_jsonp_keys, :merge_cached_responses_whitelist,
:strip_query_params, :proxied_request_host, :proxied_request_port, :cache_request_body_methods
:strip_query_params, :proxied_request_host, :proxied_request_port, :cache_request_body_methods, :after_cache_handles_request

def initialize
@logger = defined?(Rails) ? Rails.logger : Logger.new(STDOUT)
Expand Down Expand Up @@ -40,6 +40,7 @@ def reset
@proxied_request_host = nil
@proxied_request_port = 80
@cache_request_body_methods = ['post']
@after_cache_handles_request = nil
end
end

Expand Down
5 changes: 5 additions & 0 deletions lib/billy/handlers/cache_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,11 @@ def handle_request(method, url, headers, body)
replace_response_callback(response, url)
end

if Billy.config.after_cache_handles_request
request = { method: method, url: url, headers: headers, body: body }
Billy.config.after_cache_handles_request.call(request, response)
end

return response
end
end
Expand Down
17 changes: 17 additions & 0 deletions spec/lib/billy/handlers/cache_handler_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,23 @@
other_request[:headers],
other_request[:body])).to eql(status: 200, headers: { 'Connection' => 'close' }, content: 'no jsonp but has parentheses()')
end

context 'when after_cache_handles_request is set' do
it "should call the callback with the request and response" do
allow(Billy.config).to receive(:after_cache_handles_request) do
proc do |request, response|
response[:headers]['Access-Control-Allow-Origin'] = "*"
response[:content] = request[:body]
end
end
expect(Billy::Cache.instance).to receive(:cached?).and_return(true)
expect(Billy::Cache.instance).to receive(:fetch).and_return(status: 200, headers: { 'Connection' => 'close' }, content: 'The response body')
expect(handler.handle_request(request[:method],
request[:url],
request[:headers],
request[:body])).to eql(status: 200, headers: { 'Connection' => 'close', 'Access-Control-Allow-Origin' => "*" }, content: 'Some body')
end
end
end

context 'updating jsonp callback names disabled' do
Expand Down

0 comments on commit 9792d17

Please sign in to comment.