faraday-http-cache 1.1.1 → 1.2.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/README.md +6 -6
- data/lib/faraday-http-cache.rb +1 -1
- data/lib/faraday/http_cache.rb +7 -5
- data/lib/faraday/http_cache/cache_control.rb +2 -2
- data/lib/faraday/http_cache/request.rb +1 -2
- data/lib/faraday/http_cache/response.rb +1 -1
- data/spec/http_cache_spec.rb +17 -16
- data/spec/instrumentation_spec.rb +2 -2
- data/spec/request_spec.rb +0 -1
- data/spec/storage_spec.rb +5 -4
- data/spec/support/test_app.rb +1 -2
- data/spec/support/test_server.rb +5 -4
- data/spec/validation_spec.rb +4 -4
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ed664b05e7052722cfb0f9d0ba7336b6de8ea5b7
|
4
|
+
data.tar.gz: fece9174d01e39d9e63c92f0ae6ba28c676a3504
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: db36959ac2578e4f9559aece670ab1a8fcc58d33d87bceb24dd9ea6871260d0af88ad570907198e01a4d733e146e884d5fca62ffec2223b61d1b2bd6aba8d399
|
7
|
+
data.tar.gz: de95b997afd0c83d6e1b344e5e00f9bd0e2a6ce57c7d81bbde0bc5a8ac6f4efbe804087c2565c89ec879145c5e06e00ced67d491e77cfe2515c9900817063676
|
data/README.md
CHANGED
@@ -84,7 +84,7 @@ client.get('http://site/api/users')
|
|
84
84
|
In addition to logging you can instrument the middleware by passing in an `:instrumenter` option
|
85
85
|
such as ActiveSupport::Notifications (compatible objects are also allowed).
|
86
86
|
|
87
|
-
The event `
|
87
|
+
The event `http_cache.faraday` will be published every time the middleware
|
88
88
|
processes a request. In the event payload, `:env` contains the response Faraday env and
|
89
89
|
`:cache_status` contains a Symbol indicating the status of the cache processing for that request:
|
90
90
|
|
@@ -102,18 +102,18 @@ client = Faraday.new do |builder|
|
|
102
102
|
end
|
103
103
|
|
104
104
|
# Subscribes to all events from Faraday::HttpCache.
|
105
|
-
ActiveSupport::Notifications.subscribe "
|
105
|
+
ActiveSupport::Notifications.subscribe "http_cache.faraday" do |*args|
|
106
106
|
event = ActiveSupport::Notifications::Event.new(*args)
|
107
|
-
cache_status = event.payload
|
107
|
+
cache_status = event.payload[:cache_status]
|
108
108
|
statsd = Statsd.new
|
109
109
|
|
110
110
|
case cache_status
|
111
111
|
when :fresh, :valid
|
112
|
-
statsd.increment(
|
112
|
+
statsd.increment('api-calls.cache_hits')
|
113
113
|
when :invalid, :miss
|
114
|
-
statsd.increment(
|
114
|
+
statsd.increment('api-calls.cache_misses')
|
115
115
|
when :unacceptable
|
116
|
-
statsd.increment(
|
116
|
+
statsd.increment('api-calls.cache_bypass')
|
117
117
|
end
|
118
118
|
end
|
119
119
|
```
|
data/lib/faraday-http-cache.rb
CHANGED
@@ -1 +1 @@
|
|
1
|
-
require 'faraday/http_cache'
|
1
|
+
require 'faraday/http_cache' # rubocop:disable Style/FileName
|
data/lib/faraday/http_cache.rb
CHANGED
@@ -44,14 +44,14 @@ module Faraday
|
|
44
44
|
# end
|
45
45
|
class HttpCache < Faraday::Middleware
|
46
46
|
# Internal: valid options for the 'initialize' configuration Hash.
|
47
|
-
VALID_OPTIONS = [:store, :serializer, :logger, :shared_cache, :instrumenter]
|
47
|
+
VALID_OPTIONS = [:store, :serializer, :logger, :shared_cache, :instrumenter, :instrument_name]
|
48
48
|
|
49
49
|
UNSAFE_METHODS = [:post, :put, :delete, :patch]
|
50
50
|
|
51
51
|
ERROR_STATUSES = 400..499
|
52
52
|
|
53
53
|
# The name of the instrumentation event.
|
54
|
-
EVENT_NAME = '
|
54
|
+
EVENT_NAME = 'http_cache.faraday'
|
55
55
|
|
56
56
|
CACHE_STATUSES = [
|
57
57
|
# The request was not cacheable:
|
@@ -328,8 +328,7 @@ module Faraday
|
|
328
328
|
|
329
329
|
method = @request.method.to_s.upcase
|
330
330
|
path = @request.url.request_uri
|
331
|
-
|
332
|
-
@logger.debug(line)
|
331
|
+
@logger.debug { "HTTP Cache: [#{method} #{path}] #{@trace.join(', ')}" }
|
333
332
|
end
|
334
333
|
|
335
334
|
# Internal: instruments the request processing.
|
@@ -344,13 +343,16 @@ module Faraday
|
|
344
343
|
}
|
345
344
|
|
346
345
|
@instrumenter.instrument(@instrument_name, payload)
|
346
|
+
# DEPRECATED: Event name from the 1.1.1 release that isn't compatible
|
347
|
+
# with the `ActiveSupport::LogSubscriber` API.
|
348
|
+
@instrumenter.instrument('process_request.http_cache.faraday', payload)
|
347
349
|
end
|
348
350
|
|
349
351
|
# Internal: Extracts the cache status from a trace.
|
350
352
|
#
|
351
353
|
# Returns the Symbol status or nil if none was available.
|
352
354
|
def extract_status(trace)
|
353
|
-
CACHE_STATUSES.
|
355
|
+
CACHE_STATUSES.find { |status| trace.include?(status) }
|
354
356
|
end
|
355
357
|
|
356
358
|
# Internal: Checks if the given 'options' Hash contains only
|
@@ -5,7 +5,6 @@ module Faraday
|
|
5
5
|
# It breaks the several directives into keys/values and stores them into
|
6
6
|
# a Hash.
|
7
7
|
class CacheControl
|
8
|
-
|
9
8
|
# Internal: Initialize a new CacheControl.
|
10
9
|
def initialize(header)
|
11
10
|
@directives = parse(header.to_s)
|
@@ -74,7 +73,8 @@ module Faraday
|
|
74
73
|
#
|
75
74
|
# Returns the Cache Control string.
|
76
75
|
def to_s
|
77
|
-
booleans
|
76
|
+
booleans = []
|
77
|
+
values = []
|
78
78
|
|
79
79
|
@directives.each do |key, value|
|
80
80
|
if value == true
|
@@ -2,7 +2,6 @@ module Faraday
|
|
2
2
|
class HttpCache < Faraday::Middleware
|
3
3
|
# Internal: A class to represent a request
|
4
4
|
class Request
|
5
|
-
|
6
5
|
class << self
|
7
6
|
def from_env(env)
|
8
7
|
hash = env.to_hash
|
@@ -13,7 +12,7 @@ module Faraday
|
|
13
12
|
attr_reader :method, :url, :headers
|
14
13
|
|
15
14
|
def initialize(options)
|
16
|
-
@method, @url, @headers = options
|
15
|
+
@method, @url, @headers = options.values_at(:method, :url, :headers)
|
17
16
|
end
|
18
17
|
|
19
18
|
# Internal: Validates if the current request method is valid for caching.
|
@@ -175,7 +175,7 @@ module Faraday
|
|
175
175
|
#
|
176
176
|
# Returns the Time object, or nil if the header isn't present or isn't RFC 2616 compliant.
|
177
177
|
def expires
|
178
|
-
@expires ||= headers['Expires'] && Time.httpdate(headers['Expires']) rescue nil
|
178
|
+
@expires ||= headers['Expires'] && Time.httpdate(headers['Expires']) rescue nil # rubocop:disable Style/RescueModifier
|
179
179
|
end
|
180
180
|
|
181
181
|
# Internal: Gets the 'CacheControl' object.
|
data/spec/http_cache_spec.rb
CHANGED
@@ -9,6 +9,7 @@ describe Faraday::HttpCache do
|
|
9
9
|
stack.use Faraday::HttpCache, options
|
10
10
|
adapter = ENV['FARADAY_ADAPTER']
|
11
11
|
stack.headers['X-Faraday-Adapter'] = adapter
|
12
|
+
stack.headers['Content-Type'] = 'application/x-www-form-urlencoded'
|
12
13
|
stack.adapter adapter.to_sym
|
13
14
|
end
|
14
15
|
end
|
@@ -23,7 +24,7 @@ describe Faraday::HttpCache do
|
|
23
24
|
end
|
24
25
|
|
25
26
|
it 'logs that a POST request is unacceptable' do
|
26
|
-
expect(logger).to receive(:debug).
|
27
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [POST /post] unacceptable, delete') }
|
27
28
|
client.post('post').body
|
28
29
|
end
|
29
30
|
|
@@ -45,7 +46,7 @@ describe Faraday::HttpCache do
|
|
45
46
|
end
|
46
47
|
|
47
48
|
it 'logs that a POST request was deleted from the cache' do
|
48
|
-
expect(logger).to receive(:debug).
|
49
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [POST /counter] unacceptable, delete') }
|
49
50
|
client.post('counter')
|
50
51
|
end
|
51
52
|
|
@@ -62,7 +63,7 @@ describe Faraday::HttpCache do
|
|
62
63
|
end
|
63
64
|
|
64
65
|
it 'logs that a PUT request was deleted from the cache' do
|
65
|
-
expect(logger).to receive(:debug).
|
66
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [PUT /counter] unacceptable, delete') }
|
66
67
|
client.put('counter')
|
67
68
|
end
|
68
69
|
|
@@ -73,7 +74,7 @@ describe Faraday::HttpCache do
|
|
73
74
|
end
|
74
75
|
|
75
76
|
it 'logs that a DELETE request was deleted from the cache' do
|
76
|
-
expect(logger).to receive(:debug).
|
77
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [DELETE /counter] unacceptable, delete') }
|
77
78
|
client.delete('counter')
|
78
79
|
end
|
79
80
|
|
@@ -84,12 +85,12 @@ describe Faraday::HttpCache do
|
|
84
85
|
end
|
85
86
|
|
86
87
|
it 'logs that a PATCH request was deleted from the cache' do
|
87
|
-
expect(logger).to receive(:debug).
|
88
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [PATCH /counter] unacceptable, delete') }
|
88
89
|
client.patch('counter')
|
89
90
|
end
|
90
91
|
|
91
92
|
it 'logs that a response with a bad status code is invalid' do
|
92
|
-
expect(logger).to receive(:debug).
|
93
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /broken] miss, invalid') }
|
93
94
|
client.get('broken')
|
94
95
|
end
|
95
96
|
|
@@ -115,7 +116,7 @@ describe Faraday::HttpCache do
|
|
115
116
|
end
|
116
117
|
|
117
118
|
it 'logs that a private response is invalid' do
|
118
|
-
expect(logger).to receive(:debug).
|
119
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /private] miss, invalid') }
|
119
120
|
client.get('private')
|
120
121
|
end
|
121
122
|
end
|
@@ -129,7 +130,7 @@ describe Faraday::HttpCache do
|
|
129
130
|
end
|
130
131
|
|
131
132
|
it 'logs that a private response is stored' do
|
132
|
-
expect(logger).to receive(:debug).
|
133
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /private] miss, store') }
|
133
134
|
client.get('private')
|
134
135
|
end
|
135
136
|
end
|
@@ -140,7 +141,7 @@ describe Faraday::HttpCache do
|
|
140
141
|
end
|
141
142
|
|
142
143
|
it 'logs that a response with a no-store directive is invalid' do
|
143
|
-
expect(logger).to receive(:debug).
|
144
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /dontstore] miss, invalid') }
|
144
145
|
client.get('dontstore')
|
145
146
|
end
|
146
147
|
|
@@ -168,7 +169,7 @@ describe Faraday::HttpCache do
|
|
168
169
|
end
|
169
170
|
|
170
171
|
it 'logs that a request with the "Expires" is fresh and stored' do
|
171
|
-
expect(logger).to receive(:debug).
|
172
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /expires] miss, store') }
|
172
173
|
client.get('expires')
|
173
174
|
end
|
174
175
|
|
@@ -190,20 +191,20 @@ describe Faraday::HttpCache do
|
|
190
191
|
end
|
191
192
|
|
192
193
|
it 'logs that a GET response is stored' do
|
193
|
-
expect(logger).to receive(:debug).
|
194
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /get] miss, store') }
|
194
195
|
client.get('get')
|
195
196
|
end
|
196
197
|
|
197
198
|
it 'differs requests with different query strings in the log' do
|
198
|
-
expect(logger).to receive(:debug).
|
199
|
-
expect(logger).to receive(:debug).
|
199
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /get] miss, store') }
|
200
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /get?q=what] miss, store') }
|
200
201
|
client.get('get')
|
201
202
|
client.get('get', q: 'what')
|
202
203
|
end
|
203
204
|
|
204
205
|
it 'logs that a stored GET response is fresh' do
|
205
206
|
client.get('get')
|
206
|
-
expect(logger).to receive(:debug).
|
207
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /get] fresh') }
|
207
208
|
client.get('get')
|
208
209
|
end
|
209
210
|
|
@@ -214,7 +215,7 @@ describe Faraday::HttpCache do
|
|
214
215
|
|
215
216
|
it 'logs that the request with "Last-Modified" was revalidated' do
|
216
217
|
client.get('timestamped')
|
217
|
-
expect(logger).to receive(:debug).
|
218
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /timestamped] valid, store') }
|
218
219
|
expect(client.get('timestamped').body).to eq('1')
|
219
220
|
end
|
220
221
|
|
@@ -225,7 +226,7 @@ describe Faraday::HttpCache do
|
|
225
226
|
|
226
227
|
it 'logs that the request with "ETag" was revalidated' do
|
227
228
|
client.get('etag')
|
228
|
-
expect(logger).to receive(:debug).
|
229
|
+
expect(logger).to receive(:debug) { |&block| expect(block.call).to eq('HTTP Cache: [GET /etag] valid, store') }
|
229
230
|
expect(client.get('etag').body).to eq('1')
|
230
231
|
end
|
231
232
|
|
@@ -11,10 +11,10 @@ describe 'Instrumentation' do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
let(:events) { [] }
|
14
|
-
let(:subscriber) { lambda {|*args| events << ActiveSupport::Notifications::Event.new(*args) } }
|
14
|
+
let(:subscriber) { lambda { |*args| events << ActiveSupport::Notifications::Event.new(*args) } }
|
15
15
|
|
16
16
|
around do |example|
|
17
|
-
ActiveSupport::Notifications.subscribed(subscriber, '
|
17
|
+
ActiveSupport::Notifications.subscribed(subscriber, 'http_cache.faraday') do
|
18
18
|
example.run
|
19
19
|
end
|
20
20
|
end
|
data/spec/request_spec.rb
CHANGED
data/spec/storage_spec.rb
CHANGED
@@ -52,7 +52,9 @@ describe Faraday::HttpCache::Storage do
|
|
52
52
|
logger = double(:logger, warn: nil)
|
53
53
|
storage = Faraday::HttpCache::Storage.new(logger: logger)
|
54
54
|
|
55
|
-
expect {
|
55
|
+
expect {
|
56
|
+
storage.write(request, response)
|
57
|
+
}.to raise_error(Encoding::UndefinedConversionError)
|
56
58
|
expect(logger).to have_received(:warn).with(
|
57
59
|
'Response could not be serialized: "\xE2" from ASCII-8BIT to UTF-8. Try using Marshal to serialize.'
|
58
60
|
)
|
@@ -125,8 +127,8 @@ describe Faraday::HttpCache::Storage do
|
|
125
127
|
|
126
128
|
it 'is fresh until cached and that 1 second elapses then the response is no longer fresh' do
|
127
129
|
headers = {
|
128
|
-
|
129
|
-
|
130
|
+
'Date' => (Time.now - 39).httpdate,
|
131
|
+
'Expires' => (Time.now + 40).httpdate
|
130
132
|
}
|
131
133
|
|
132
134
|
response = Faraday::HttpCache::Response.new(response_headers: headers)
|
@@ -138,5 +140,4 @@ describe Faraday::HttpCache::Storage do
|
|
138
140
|
expect(cached_response).not_to be_fresh
|
139
141
|
end
|
140
142
|
end
|
141
|
-
|
142
143
|
end
|
data/spec/support/test_app.rb
CHANGED
@@ -2,7 +2,6 @@ require 'sinatra/base'
|
|
2
2
|
require 'json'
|
3
3
|
|
4
4
|
class TestApp < Sinatra::Base
|
5
|
-
|
6
5
|
set :environment, :test
|
7
6
|
set :server, 'webrick'
|
8
7
|
disable :protection
|
@@ -104,7 +103,7 @@ class TestApp < Sinatra::Base
|
|
104
103
|
tag = settings.counter > 2 ? '1' : '2'
|
105
104
|
|
106
105
|
if env['HTTP_IF_NONE_MATCH'] == tag
|
107
|
-
[304, { 'ETag' => tag, 'Cache-Control' => 'max-age=200', 'Date' => Time.now.httpdate, 'Expires' => (Time.now + 200).httpdate, 'Vary' => '*' },
|
106
|
+
[304, { 'ETag' => tag, 'Cache-Control' => 'max-age=200', 'Date' => Time.now.httpdate, 'Expires' => (Time.now + 200).httpdate, 'Vary' => '*' }, '']
|
108
107
|
else
|
109
108
|
[200, { 'ETag' => tag, 'Cache-Control' => 'max-age=0', 'Date' => settings.yesterday, 'Expires' => Time.now.httpdate, 'Vary' => 'Accept' }, increment_counter]
|
110
109
|
end
|
data/spec/support/test_server.rb
CHANGED
@@ -27,7 +27,7 @@ class TestServer
|
|
27
27
|
log.sync = true
|
28
28
|
webrick_opts = {
|
29
29
|
Port: @port,
|
30
|
-
Logger: WEBrick::Log
|
30
|
+
Logger: WEBrick::Log.new(log),
|
31
31
|
AccessLog: [[log, '[%{X-Faraday-Adapter}i] %m %U -> %s %b']]
|
32
32
|
}
|
33
33
|
Rack::Handler::WEBrick.run(TestApp, webrick_opts)
|
@@ -38,7 +38,7 @@ class TestServer
|
|
38
38
|
conn = Net::HTTP.new @host, @port
|
39
39
|
conn.open_timeout = conn.read_timeout = 0.1
|
40
40
|
|
41
|
-
responsive =
|
41
|
+
responsive = ->(path) { # rubocop:disable Style/BlockDelimiters
|
42
42
|
begin
|
43
43
|
res = conn.start { conn.get(path) }
|
44
44
|
res.is_a?(Net::HTTPSuccess)
|
@@ -48,11 +48,12 @@ class TestServer
|
|
48
48
|
}
|
49
49
|
|
50
50
|
server_pings = 0
|
51
|
-
|
51
|
+
loop do
|
52
|
+
break if responsive.call('/ping')
|
52
53
|
server_pings += 1
|
53
54
|
sleep 0.05
|
54
55
|
abort 'test server did not managed to start' if server_pings >= 50
|
55
|
-
end
|
56
|
+
end
|
56
57
|
end
|
57
58
|
|
58
59
|
def find_port
|
data/spec/validation_spec.rb
CHANGED
@@ -11,11 +11,11 @@ describe Faraday::HttpCache do
|
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'maintains the "Content-Type" header for cached responses' do
|
14
|
-
backend.get('/test') { [200, { 'ETag' => '123ABC', 'Content-Type' => 'x' },
|
14
|
+
backend.get('/test') { [200, { 'ETag' => '123ABC', 'Content-Type' => 'x' }, ''] }
|
15
15
|
first_content_type = client.get('/test').headers['Content-Type']
|
16
16
|
|
17
17
|
# The Content-Type header of the validation response should be ignored.
|
18
|
-
backend.get('/test') { [304, { 'Content-Type' => 'y' },
|
18
|
+
backend.get('/test') { [304, { 'Content-Type' => 'y' }, ''] }
|
19
19
|
second_content_type = client.get('/test').headers['Content-Type']
|
20
20
|
|
21
21
|
expect(first_content_type).to eq('x')
|
@@ -23,11 +23,11 @@ describe Faraday::HttpCache do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
it 'maintains the "Content-Length" header for cached responses' do
|
26
|
-
backend.get('/test') { [200, { 'ETag' => '123ABC', 'Content-Length' => 1 },
|
26
|
+
backend.get('/test') { [200, { 'ETag' => '123ABC', 'Content-Length' => 1 }, ''] }
|
27
27
|
first_content_length = client.get('/test').headers['Content-Length']
|
28
28
|
|
29
29
|
# The Content-Length header of the validation response should be ignored.
|
30
|
-
backend.get('/test') { [304, { 'Content-Length' => 2 },
|
30
|
+
backend.get('/test') { [304, { 'Content-Length' => 2 }, ''] }
|
31
31
|
second_content_length = client.get('/test').headers['Content-Length']
|
32
32
|
|
33
33
|
expect(first_content_length).to eq(1)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: faraday-http-cache
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Lucas Mazza
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-08-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|