httparty-cache 0.0.1
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 +7 -0
- data/README.md +82 -0
- data/lib/httparty/cache/request.rb +117 -0
- data/lib/httparty/cache/response.rb +78 -0
- data/lib/httparty/cache/store/abstract.rb +59 -0
- data/lib/httparty/cache/store/jekyll.rb +37 -0
- data/lib/httparty/cache/store/memory.rb +33 -0
- data/lib/httparty/cache/store/redis.rb +90 -0
- data/lib/httparty/cache/store.rb +8 -0
- data/lib/httparty/cache.rb +46 -0
- metadata +259 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ff16750de74919a4428091908be24f05775deded7885af69960c38265ee1679b
|
4
|
+
data.tar.gz: 12ccabffc3f4d24dfeef6327a3ac5649560b275051840826f31c3482e2075b2d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: f2d9b8a53ed1ef26b0ab22dc64108ea69cecfc76c13505b4d184e2df0823ddb78857ccf815152bc1adf202a94a0b1a3010af4c7714012842f675ee3428c6109e
|
7
|
+
data.tar.gz: 5b33148ca9f3d650218f66ca59964c04c91e87dfa730f8cd997aaad87fe36d19decdf1833463512ecc3f457cbe1bb8b5fbe7c5f4527325fe686cde1718b335e7
|
data/README.md
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
# HTTParty cache
|
2
|
+
|
3
|
+
Implements [HTTP caching][] support to [HTTParty][] requests by following
|
4
|
+
servers' headers such as [Cache-Control][], specifically the `max-age`,
|
5
|
+
`must-revalidate` and`no-cache` directives, [Vary][], [ETag][],
|
6
|
+
[Last-Modified][] to perform response [validation][].
|
7
|
+
|
8
|
+
[HTTP caching]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching
|
9
|
+
[Cache-Control]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/cache-control
|
10
|
+
[Vary]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/vary
|
11
|
+
[ETag]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/etag
|
12
|
+
[Last-Modified]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/last-modified
|
13
|
+
[validation]: https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#validation
|
14
|
+
[HTTParty]: https://github.com/jnunemaker/httparty
|
15
|
+
|
16
|
+
## Use
|
17
|
+
|
18
|
+
Add this gem to your `Gemfile` and install dependencies.
|
19
|
+
|
20
|
+
Configure your `HTTParty` client to use a cache store and perform
|
21
|
+
caching:
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
require 'httparty'
|
25
|
+
require 'httparty/cache'
|
26
|
+
|
27
|
+
class Client
|
28
|
+
include HTTParty
|
29
|
+
include HTTParty::Cache
|
30
|
+
|
31
|
+
caching true
|
32
|
+
cache_store :memory
|
33
|
+
end
|
34
|
+
```
|
35
|
+
|
36
|
+
### Cache stores
|
37
|
+
|
38
|
+
#### Redis
|
39
|
+
|
40
|
+
If you want to use Redis as a cache store:
|
41
|
+
|
42
|
+
1. Add `redis-client` and optionally `hiredis-client` gems to your
|
43
|
+
`Gemfile`.
|
44
|
+
|
45
|
+
2. Set the environment variable `REDIS_URL` with the server URL, or
|
46
|
+
initialize the cache store with a custom URL.
|
47
|
+
|
48
|
+
```ruby
|
49
|
+
require 'httparty'
|
50
|
+
require 'httparty/cache'
|
51
|
+
require 'httparty/cache/store/redis'
|
52
|
+
|
53
|
+
class Client
|
54
|
+
include HTTParty
|
55
|
+
include HTTParty::Cache
|
56
|
+
|
57
|
+
caching true
|
58
|
+
cache_store :redis
|
59
|
+
# or
|
60
|
+
cache_store HTTParty::Cache::Store::Redis.new(redis_url: 'redis://redis.provider:6379')
|
61
|
+
end
|
62
|
+
```
|
63
|
+
|
64
|
+
#### Jekyll
|
65
|
+
|
66
|
+
If you want to use Jekyll as a cache store, for instance while writing
|
67
|
+
a plugin using HTTParty:
|
68
|
+
|
69
|
+
```ruby
|
70
|
+
require 'httparty'
|
71
|
+
require 'httparty/cache'
|
72
|
+
require 'httparty/cache/store/jekyll'
|
73
|
+
|
74
|
+
class Client
|
75
|
+
include HTTParty
|
76
|
+
include HTTParty::Cache
|
77
|
+
|
78
|
+
caching true
|
79
|
+
cache_store :jekyll
|
80
|
+
# or
|
81
|
+
cache_store HTTParty::Cache::Store::Jekyll.new(name: 'My::Jekyll::Cache')
|
82
|
+
end
|
@@ -0,0 +1,117 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
module Cache
|
5
|
+
# Extends HTTParty::Request with caching methods
|
6
|
+
#
|
7
|
+
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching}
|
8
|
+
module Request
|
9
|
+
CACHE_REVALIDATION_HEADERS = {
|
10
|
+
'ETag' => 'If-None-Match',
|
11
|
+
'Last-Modified' => 'If-Modified-Since'
|
12
|
+
}.freeze
|
13
|
+
|
14
|
+
# Calculates a cache key from URI + query string + headers
|
15
|
+
#
|
16
|
+
# @return [String]
|
17
|
+
def cache_key
|
18
|
+
@cache_key ||= "request:#{uri}##{URI.encode_www_form(options[:headers] || {})}"
|
19
|
+
end
|
20
|
+
|
21
|
+
def validate
|
22
|
+
super
|
23
|
+
|
24
|
+
raise ArgumentError, 'Caching is enabled but store was not provided' if caching? && cache_store.nil?
|
25
|
+
end
|
26
|
+
|
27
|
+
# Patch HTTParty::Request#perform to provide caching for GET
|
28
|
+
# requests
|
29
|
+
#
|
30
|
+
# @return [HTTParty::Response]
|
31
|
+
def perform(&block)
|
32
|
+
return super(&block) unless caching? && http_method == Net::HTTP::Get
|
33
|
+
|
34
|
+
if cached?
|
35
|
+
handle_revalidation
|
36
|
+
else
|
37
|
+
super(&block).tap do |response|
|
38
|
+
# Point current request to cached response
|
39
|
+
cache_store.set(response.cache_key, response)
|
40
|
+
cache_store.set(cache_key, response.cache_key)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
# When the request is performed for the first time or has been
|
46
|
+
# evicted from cache or is corrupted
|
47
|
+
#
|
48
|
+
# @return [Bool]
|
49
|
+
def cached?
|
50
|
+
cache_store.key?(cache_key) &&
|
51
|
+
cache_store.key?(cache_store.get(cache_key)) &&
|
52
|
+
cache_store.get(cache_store.get(cache_key)).is_a?(HTTParty::Response)
|
53
|
+
end
|
54
|
+
|
55
|
+
def caching?
|
56
|
+
!!options[:caching]
|
57
|
+
end
|
58
|
+
|
59
|
+
private
|
60
|
+
|
61
|
+
# Revalidates request
|
62
|
+
#
|
63
|
+
# @return [HTTParty::Response]
|
64
|
+
def handle_revalidation
|
65
|
+
cached_response = cache_store.get(cache_store.get(cache_key))
|
66
|
+
|
67
|
+
if cached_response.revalidate? || cached_response.stale?
|
68
|
+
self.http_method = Net::HTTP::Head
|
69
|
+
options[:cached_response] = cached_response
|
70
|
+
|
71
|
+
add_cache_revalidation_headers
|
72
|
+
|
73
|
+
response = perform
|
74
|
+
|
75
|
+
if response.not_modified?
|
76
|
+
cached_response.headers['date'] = response.headers['date']
|
77
|
+
response = cached_response
|
78
|
+
else
|
79
|
+
self.http_method = Net::HTTP::Get
|
80
|
+
# Remove from cache so we can perform the request, otherwise
|
81
|
+
# we produce an infinite loop
|
82
|
+
cache_store.delete(cache_key)
|
83
|
+
response = perform
|
84
|
+
end
|
85
|
+
|
86
|
+
cache_store.set(response.cache_key, response)
|
87
|
+
response
|
88
|
+
else
|
89
|
+
cached_response
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# Just a shortcut
|
94
|
+
def cache_store
|
95
|
+
options[:cache_store]
|
96
|
+
end
|
97
|
+
|
98
|
+
# Adds revalidation headers unless they're already present
|
99
|
+
#
|
100
|
+
# @return [nil]
|
101
|
+
def add_cache_revalidation_headers
|
102
|
+
options[:headers] ||= {}
|
103
|
+
|
104
|
+
CACHE_REVALIDATION_HEADERS.each_pair do |original_header, revalidation_header|
|
105
|
+
next if (value = options[:cached_response].headers[original_header]).nil?
|
106
|
+
|
107
|
+
options[:headers][revalidation_header] ||= value
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Patch HTTParty::Request
|
115
|
+
HTTParty::Request.class_eval do
|
116
|
+
prepend HTTParty::Cache::Request
|
117
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
module Cache
|
5
|
+
# Extends HTTParty::Response with caching methods
|
6
|
+
#
|
7
|
+
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching}
|
8
|
+
module Response
|
9
|
+
# Detects if response is cached
|
10
|
+
def cached?
|
11
|
+
code == 304
|
12
|
+
end
|
13
|
+
|
14
|
+
# Parses Cache-Control headers
|
15
|
+
#
|
16
|
+
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/cache-control}
|
17
|
+
# @return [Hash]
|
18
|
+
def cache_control
|
19
|
+
@cache_control ||= headers['Cache-Control'].to_s.downcase.split(',').map(&:strip).map do |c|
|
20
|
+
k, v = c.split('=', 2).map(&:strip)
|
21
|
+
|
22
|
+
[k.tr('-', '_').to_sym, (v ? Integer(v) : true)]
|
23
|
+
end.to_h
|
24
|
+
end
|
25
|
+
|
26
|
+
# Returns the request date
|
27
|
+
#
|
28
|
+
# @return [Time]
|
29
|
+
def date
|
30
|
+
Time.parse(headers['date'])
|
31
|
+
rescue TypeError, ArgumentError
|
32
|
+
raise HTTParty::ResponseError, response
|
33
|
+
end
|
34
|
+
|
35
|
+
# Returns the current age of the request in seconds
|
36
|
+
#
|
37
|
+
# @return [Integer]
|
38
|
+
def age
|
39
|
+
(Time.now - date).to_i
|
40
|
+
rescue HTTParty::ResponseError
|
41
|
+
0
|
42
|
+
end
|
43
|
+
|
44
|
+
# The response is stale when it has been cached for more than the
|
45
|
+
# allowed max age
|
46
|
+
#
|
47
|
+
# @return [Bool]
|
48
|
+
def stale?
|
49
|
+
!cache_control[:max_age].nil? && age > cache_control[:max_age]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Detects if the response must be revalidated even if still fresh.
|
53
|
+
#
|
54
|
+
# @see {https://developer.mozilla.org/en-US/docs/Web/HTTP/Caching#force_revalidation}
|
55
|
+
# @return [Bool]
|
56
|
+
def revalidate?
|
57
|
+
!!(cache_control[:no_cache] || (cache_control[:max_age]&.zero? && cache_control[:must_revalidate]))
|
58
|
+
end
|
59
|
+
|
60
|
+
# Returns the request headers that vary responses
|
61
|
+
#
|
62
|
+
# @return [Hash]
|
63
|
+
def vary
|
64
|
+
@vary ||= request.options[:headers].to_h.slice(*headers['Vary'].to_s.split(',').map(&:strip).sort)
|
65
|
+
end
|
66
|
+
|
67
|
+
# Generates a cache key
|
68
|
+
#
|
69
|
+
# @return [String]
|
70
|
+
def cache_key
|
71
|
+
@cache_key ||= "response:#{request.uri}##{URI.encode_www_form vary}"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
# Patch HTTParty::Response
|
78
|
+
HTTParty::Response.include HTTParty::Cache::Response
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
module Cache
|
5
|
+
module Store
|
6
|
+
# Cache store
|
7
|
+
class Abstract
|
8
|
+
# @return [Hash]
|
9
|
+
attr_reader :options
|
10
|
+
|
11
|
+
# @param :key [String]
|
12
|
+
# @return [Response,nil]
|
13
|
+
def get(key)
|
14
|
+
raise NotImplementedError
|
15
|
+
end
|
16
|
+
|
17
|
+
# @param :key [String]
|
18
|
+
# @param :response [Response]
|
19
|
+
# @return [Response]
|
20
|
+
def set(key, response)
|
21
|
+
raise NotImplementedError
|
22
|
+
end
|
23
|
+
|
24
|
+
# @param :key [String]
|
25
|
+
# @return nil
|
26
|
+
def delete(key)
|
27
|
+
raise NotImplementedError
|
28
|
+
end
|
29
|
+
|
30
|
+
# @param :key [String]
|
31
|
+
# @yield
|
32
|
+
def getset(key, &block)
|
33
|
+
raise NotImplementedError
|
34
|
+
end
|
35
|
+
|
36
|
+
# @param :key [String]
|
37
|
+
# @return [Boolean]
|
38
|
+
def key?(key)
|
39
|
+
raise NotImplementedError
|
40
|
+
end
|
41
|
+
|
42
|
+
def clear
|
43
|
+
raise NotImplementedError
|
44
|
+
end
|
45
|
+
|
46
|
+
def marshal_dump
|
47
|
+
[
|
48
|
+
self.class.name,
|
49
|
+
options || {}
|
50
|
+
]
|
51
|
+
end
|
52
|
+
|
53
|
+
def marshal_load(array)
|
54
|
+
Object.const_get(array.first).new(**array.last)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'abstract'
|
4
|
+
require 'jekyll/cache'
|
5
|
+
|
6
|
+
module HTTParty
|
7
|
+
module Cache
|
8
|
+
module Store
|
9
|
+
class Jekyll < Abstract
|
10
|
+
extend Forwardable
|
11
|
+
|
12
|
+
def_delegators :@store, :key?, :delete, :clear, :getset
|
13
|
+
|
14
|
+
# @return [Hash]
|
15
|
+
attr_reader :options
|
16
|
+
|
17
|
+
# @param :name [String]
|
18
|
+
def initialize(name: self.class.name)
|
19
|
+
@options = {}
|
20
|
+
@options[:name] = name
|
21
|
+
@store = ::Jekyll::Cache.new(name)
|
22
|
+
end
|
23
|
+
|
24
|
+
def set(key, response)
|
25
|
+
@store[key] = response
|
26
|
+
response
|
27
|
+
end
|
28
|
+
|
29
|
+
def get(key)
|
30
|
+
@store[key]
|
31
|
+
rescue RuntimeError
|
32
|
+
nil
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'abstract'
|
4
|
+
|
5
|
+
module HTTParty
|
6
|
+
module Cache
|
7
|
+
module Store
|
8
|
+
class Memory < Abstract
|
9
|
+
extend Forwardable
|
10
|
+
|
11
|
+
attr_reader :store
|
12
|
+
|
13
|
+
def_delegator :@store, :[], :get
|
14
|
+
def_delegator :@store, :[]=, :set
|
15
|
+
|
16
|
+
def_delegators :@store, :key?, :delete
|
17
|
+
|
18
|
+
def initialize(**)
|
19
|
+
clear
|
20
|
+
end
|
21
|
+
|
22
|
+
def getset(key)
|
23
|
+
store[key] ||= yield
|
24
|
+
end
|
25
|
+
|
26
|
+
def clear
|
27
|
+
@store = {}
|
28
|
+
nil
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require_relative 'abstract'
|
4
|
+
require 'redis-client'
|
5
|
+
|
6
|
+
begin
|
7
|
+
require 'hiredis-client'
|
8
|
+
RedisClient.default_driver = :hiredis
|
9
|
+
rescue LoadError
|
10
|
+
end
|
11
|
+
|
12
|
+
module HTTParty
|
13
|
+
module Cache
|
14
|
+
module Store
|
15
|
+
class Redis < Abstract
|
16
|
+
# A Marshaled `nil` value
|
17
|
+
NIL = "\x04\b0"
|
18
|
+
|
19
|
+
# @return [Hash]
|
20
|
+
attr_reader :options
|
21
|
+
|
22
|
+
# @param :redis_url [String]
|
23
|
+
def initialize(redis_url: nil)
|
24
|
+
@options = {}
|
25
|
+
@options[:redis_url] = redis_url || ENV['REDIS_URL']
|
26
|
+
@config = RedisClient.config(url: @options[:redis_url])
|
27
|
+
@redis = @config.new_pool(size: 2)
|
28
|
+
@redis.call('PING')
|
29
|
+
end
|
30
|
+
|
31
|
+
# Retrieves a key
|
32
|
+
#
|
33
|
+
# @param :key [String]
|
34
|
+
# @return [Response,nil]
|
35
|
+
def get(key)
|
36
|
+
Marshal.load(redis('GET', key) || NIL)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Stores a Marshaled value indexed by a key.
|
40
|
+
#
|
41
|
+
# @param :key [String]
|
42
|
+
# @param :response [Response]
|
43
|
+
# @return [Response]
|
44
|
+
def set(key, response)
|
45
|
+
redis('SET', key, Marshal.dump(response))
|
46
|
+
response
|
47
|
+
end
|
48
|
+
|
49
|
+
# Returns a key or set its value to a block result
|
50
|
+
#
|
51
|
+
# @param :key [String]
|
52
|
+
# @return [Response,nil]
|
53
|
+
def getset(key)
|
54
|
+
return get(key) if key?(key)
|
55
|
+
|
56
|
+
set(key, yield)
|
57
|
+
end
|
58
|
+
|
59
|
+
# Removes a key from Redis
|
60
|
+
#
|
61
|
+
# @param :key [String]
|
62
|
+
# @return [nil]
|
63
|
+
def delete(key)
|
64
|
+
redis('DEL', key)
|
65
|
+
nil
|
66
|
+
end
|
67
|
+
|
68
|
+
# Discovers if a key exists
|
69
|
+
#
|
70
|
+
# @param :key [String]
|
71
|
+
# @return [Boolean]
|
72
|
+
def key?(key)
|
73
|
+
redis('EXISTS', key).positive?
|
74
|
+
end
|
75
|
+
|
76
|
+
def clear
|
77
|
+
redis('FLUSHALL', 'SYNC')
|
78
|
+
nil
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
# Execs Redis commands and collects stats
|
84
|
+
def redis(*args)
|
85
|
+
@redis.call(*args)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module HTTParty
|
4
|
+
# HTTParty plugin to manage cache
|
5
|
+
module Cache
|
6
|
+
def self.included(base)
|
7
|
+
base.extend ClassMethods
|
8
|
+
|
9
|
+
require_relative 'cache/response'
|
10
|
+
require_relative 'cache/request'
|
11
|
+
end
|
12
|
+
|
13
|
+
module ClassMethods
|
14
|
+
# This is both a setter and a getter...
|
15
|
+
#
|
16
|
+
# @param :cache_store [Symbol,HTTParty::Cache::Store::Abstract]
|
17
|
+
# @return [HTTParty::Cache::Store::Abstract]
|
18
|
+
def cache_store(cache_store = nil)
|
19
|
+
case cache_store
|
20
|
+
when NilClass
|
21
|
+
return default_options[:cache_store]
|
22
|
+
when Symbol
|
23
|
+
require_relative "cache/store/#{cache_store}"
|
24
|
+
|
25
|
+
class_name = cache_store.to_s.split('_').map(&:capitalize).join
|
26
|
+
cache_store = Object.const_get("HTTParty::Cache::Store::#{class_name}").new
|
27
|
+
end
|
28
|
+
|
29
|
+
default_options[:cache_store] = cache_store
|
30
|
+
end
|
31
|
+
|
32
|
+
# Toggle caching
|
33
|
+
#
|
34
|
+
# @param :caching [Bool]
|
35
|
+
# @return [Bool]
|
36
|
+
def caching(caching)
|
37
|
+
default_options[:caching] = caching
|
38
|
+
end
|
39
|
+
|
40
|
+
# Sets cache_control
|
41
|
+
def cache_control(cache_control)
|
42
|
+
default_options[:cache_control] = cache_control
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
metadata
ADDED
@@ -0,0 +1,259 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: httparty-cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- f
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-01-31 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: httparty
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.18'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.18'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: activesupport
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: factory_bot
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: pry
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.6'
|
76
|
+
- - ">="
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
version: 3.6.0
|
79
|
+
type: :development
|
80
|
+
prerelease: false
|
81
|
+
version_requirements: !ruby/object:Gem::Requirement
|
82
|
+
requirements:
|
83
|
+
- - "~>"
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '3.6'
|
86
|
+
- - ">="
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: 3.6.0
|
89
|
+
- !ruby/object:Gem::Dependency
|
90
|
+
name: rspec-tap-formatters
|
91
|
+
requirement: !ruby/object:Gem::Requirement
|
92
|
+
requirements:
|
93
|
+
- - ">="
|
94
|
+
- !ruby/object:Gem::Version
|
95
|
+
version: '0'
|
96
|
+
type: :development
|
97
|
+
prerelease: false
|
98
|
+
version_requirements: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ">="
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
- !ruby/object:Gem::Dependency
|
104
|
+
name: yard
|
105
|
+
requirement: !ruby/object:Gem::Requirement
|
106
|
+
requirements:
|
107
|
+
- - ">="
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
type: :development
|
111
|
+
prerelease: false
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
name: hiredis-client
|
119
|
+
requirement: !ruby/object:Gem::Requirement
|
120
|
+
requirements:
|
121
|
+
- - "~>"
|
122
|
+
- !ruby/object:Gem::Version
|
123
|
+
version: 0.14.0
|
124
|
+
type: :development
|
125
|
+
prerelease: false
|
126
|
+
version_requirements: !ruby/object:Gem::Requirement
|
127
|
+
requirements:
|
128
|
+
- - "~>"
|
129
|
+
- !ruby/object:Gem::Version
|
130
|
+
version: 0.14.0
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
name: redis-client
|
133
|
+
requirement: !ruby/object:Gem::Requirement
|
134
|
+
requirements:
|
135
|
+
- - "~>"
|
136
|
+
- !ruby/object:Gem::Version
|
137
|
+
version: 0.14.0
|
138
|
+
type: :development
|
139
|
+
prerelease: false
|
140
|
+
version_requirements: !ruby/object:Gem::Requirement
|
141
|
+
requirements:
|
142
|
+
- - "~>"
|
143
|
+
- !ruby/object:Gem::Version
|
144
|
+
version: 0.14.0
|
145
|
+
- !ruby/object:Gem::Dependency
|
146
|
+
name: rubocop
|
147
|
+
requirement: !ruby/object:Gem::Requirement
|
148
|
+
requirements:
|
149
|
+
- - ">="
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
type: :development
|
153
|
+
prerelease: false
|
154
|
+
version_requirements: !ruby/object:Gem::Requirement
|
155
|
+
requirements:
|
156
|
+
- - ">="
|
157
|
+
- !ruby/object:Gem::Version
|
158
|
+
version: '0'
|
159
|
+
- !ruby/object:Gem::Dependency
|
160
|
+
name: timecop
|
161
|
+
requirement: !ruby/object:Gem::Requirement
|
162
|
+
requirements:
|
163
|
+
- - ">="
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
type: :development
|
167
|
+
prerelease: false
|
168
|
+
version_requirements: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: '0'
|
173
|
+
- !ruby/object:Gem::Dependency
|
174
|
+
name: jekyll
|
175
|
+
requirement: !ruby/object:Gem::Requirement
|
176
|
+
requirements:
|
177
|
+
- - ">="
|
178
|
+
- !ruby/object:Gem::Version
|
179
|
+
version: '0'
|
180
|
+
type: :development
|
181
|
+
prerelease: false
|
182
|
+
version_requirements: !ruby/object:Gem::Requirement
|
183
|
+
requirements:
|
184
|
+
- - ">="
|
185
|
+
- !ruby/object:Gem::Version
|
186
|
+
version: '0'
|
187
|
+
- !ruby/object:Gem::Dependency
|
188
|
+
name: webmock
|
189
|
+
requirement: !ruby/object:Gem::Requirement
|
190
|
+
requirements:
|
191
|
+
- - "~>"
|
192
|
+
- !ruby/object:Gem::Version
|
193
|
+
version: '1.24'
|
194
|
+
- - ">="
|
195
|
+
- !ruby/object:Gem::Version
|
196
|
+
version: 1.24.3
|
197
|
+
type: :development
|
198
|
+
prerelease: false
|
199
|
+
version_requirements: !ruby/object:Gem::Requirement
|
200
|
+
requirements:
|
201
|
+
- - "~>"
|
202
|
+
- !ruby/object:Gem::Version
|
203
|
+
version: '1.24'
|
204
|
+
- - ">="
|
205
|
+
- !ruby/object:Gem::Version
|
206
|
+
version: 1.24.3
|
207
|
+
description: A cache manager for HTTParty
|
208
|
+
email:
|
209
|
+
- f@sutty.nl
|
210
|
+
executables: []
|
211
|
+
extensions: []
|
212
|
+
extra_rdoc_files:
|
213
|
+
- README.md
|
214
|
+
files:
|
215
|
+
- README.md
|
216
|
+
- lib/httparty/cache.rb
|
217
|
+
- lib/httparty/cache/request.rb
|
218
|
+
- lib/httparty/cache/response.rb
|
219
|
+
- lib/httparty/cache/store.rb
|
220
|
+
- lib/httparty/cache/store/abstract.rb
|
221
|
+
- lib/httparty/cache/store/jekyll.rb
|
222
|
+
- lib/httparty/cache/store/memory.rb
|
223
|
+
- lib/httparty/cache/store/redis.rb
|
224
|
+
homepage: https://0xacab.org/sutty/httparty-cache
|
225
|
+
licenses:
|
226
|
+
- MIT
|
227
|
+
metadata:
|
228
|
+
bug_tracker_uri: https://0xacab.org/sutty/httparty-cache/issues
|
229
|
+
homepage_uri: https://0xacab.org/sutty/httparty-cache
|
230
|
+
source_code_uri: https://0xacab.org/sutty/httparty-cache
|
231
|
+
changelog_uri: https://0xacab.org/sutty/httparty-cache/-/blob/master/CHANGELOG.md
|
232
|
+
documentation_uri: https://rubydoc.info/gems/httparty-cache
|
233
|
+
post_install_message:
|
234
|
+
rdoc_options:
|
235
|
+
- "--title"
|
236
|
+
- httparty-cache - HTTParty cache
|
237
|
+
- "--main"
|
238
|
+
- README.md
|
239
|
+
- "--line-numbers"
|
240
|
+
- "--inline-source"
|
241
|
+
- "--quiet"
|
242
|
+
require_paths:
|
243
|
+
- lib
|
244
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
245
|
+
requirements:
|
246
|
+
- - ">="
|
247
|
+
- !ruby/object:Gem::Version
|
248
|
+
version: '2.7'
|
249
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
250
|
+
requirements:
|
251
|
+
- - ">="
|
252
|
+
- !ruby/object:Gem::Version
|
253
|
+
version: '0'
|
254
|
+
requirements: []
|
255
|
+
rubygems_version: 3.3.26
|
256
|
+
signing_key:
|
257
|
+
specification_version: 4
|
258
|
+
summary: HTTParty cache
|
259
|
+
test_files: []
|