httpdisk 0.1.0 → 0.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/.rubocop.yml +19 -0
- data/Gemfile +1 -0
- data/Gemfile.lock +21 -1
- data/README.md +7 -1
- data/Rakefile +9 -1
- data/bin/httpdisk +1 -1
- data/examples.rb +1 -2
- data/httpdisk.gemspec +2 -2
- data/lib/httpdisk/cache.rb +6 -4
- data/lib/httpdisk/cache_key.rb +2 -3
- data/lib/httpdisk/cli.rb +5 -0
- data/lib/httpdisk/client.rb +16 -3
- data/lib/httpdisk/payload.rb +4 -4
- data/lib/httpdisk/version.rb +1 -1
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d311812fa4d8d034c9eda6b9b18df36e21eb14ebc9d632cd1fe071268ca77786
|
4
|
+
data.tar.gz: 90e891451c1805d6d8ba5ad268bc2682528954a2a8acd37546f69ab43d493311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c61e162e26d8a7b86fe00165e095d72f99415e8e5a4245513758731a009186999d5cf171db45c8b83115dae8c376e8391aa0bfbd00d3a2fd086c0451f77269ad
|
7
|
+
data.tar.gz: 1ad5bdb0a51f2b84822a6164379a724a7b03338b30f9c427b956bbe4263b0326720aea3bcb02b1fa37110a8aa5adc24dc8f3f257733b11667df913b863da0d52
|
data/.rubocop.yml
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
AllCops:
|
2
|
+
NewCops: enable
|
3
|
+
SuggestExtensions: false
|
4
|
+
|
5
|
+
# minimal personal preference
|
6
|
+
Layout/CaseIndentation: { Enabled: false }
|
7
|
+
Layout/EndAlignment: { EnforcedStyleAlignWith: variable }
|
8
|
+
Lint/AssignmentInCondition: { Enabled: false }
|
9
|
+
Metrics: { Enabled: false }
|
10
|
+
Naming/MethodParameterName: { Enabled: false }
|
11
|
+
Naming/VariableNumber: { Enabled: false }
|
12
|
+
Style/Documentation: { Enabled: false }
|
13
|
+
Style/FrozenStringLiteralComment: { Enabled: false }
|
14
|
+
Style/IfUnlessModifier: { Enabled: false }
|
15
|
+
Style/NegatedIf: { Enabled: false }
|
16
|
+
Style/ParallelAssignment: { Enabled: false }
|
17
|
+
Style/StderrPuts: { Enabled: false }
|
18
|
+
Style/TrailingCommaInArrayLiteral: { EnforcedStyleForMultiline: consistent_comma }
|
19
|
+
Style/TrailingCommaInHashLiteral: { EnforcedStyleForMultiline: consistent_comma }
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
httpdisk (0.
|
4
|
+
httpdisk (0.2.0)
|
5
5
|
faraday (~> 1.4)
|
6
6
|
faraday-cookie_jar (~> 0.0)
|
7
7
|
faraday_middleware (~> 1.0)
|
@@ -12,6 +12,7 @@ GEM
|
|
12
12
|
specs:
|
13
13
|
addressable (2.7.0)
|
14
14
|
public_suffix (>= 2.0.2, < 5.0)
|
15
|
+
ast (2.4.2)
|
15
16
|
coderay (1.1.3)
|
16
17
|
crack (0.4.5)
|
17
18
|
rexml
|
@@ -38,17 +39,35 @@ GEM
|
|
38
39
|
minitest (5.14.4)
|
39
40
|
mocha (1.11.2)
|
40
41
|
multipart-post (2.1.1)
|
42
|
+
parallel (1.20.1)
|
43
|
+
parser (3.0.1.1)
|
44
|
+
ast (~> 2.4.1)
|
41
45
|
pry (0.13.1)
|
42
46
|
coderay (~> 1.1)
|
43
47
|
method_source (~> 1.0)
|
44
48
|
public_suffix (4.0.6)
|
49
|
+
rainbow (3.0.0)
|
45
50
|
rake (13.0.3)
|
51
|
+
regexp_parser (2.1.1)
|
46
52
|
rexml (3.2.5)
|
53
|
+
rubocop (1.13.0)
|
54
|
+
parallel (~> 1.10)
|
55
|
+
parser (>= 3.0.0.0)
|
56
|
+
rainbow (>= 2.2.2, < 4.0)
|
57
|
+
regexp_parser (>= 1.8, < 3.0)
|
58
|
+
rexml
|
59
|
+
rubocop-ast (>= 1.2.0, < 2.0)
|
60
|
+
ruby-progressbar (~> 1.7)
|
61
|
+
unicode-display_width (>= 1.4.0, < 3.0)
|
62
|
+
rubocop-ast (1.5.0)
|
63
|
+
parser (>= 3.0.1.1)
|
64
|
+
ruby-progressbar (1.11.0)
|
47
65
|
ruby2_keywords (0.0.4)
|
48
66
|
slop (4.8.2)
|
49
67
|
unf (0.1.4)
|
50
68
|
unf_ext
|
51
69
|
unf_ext (0.0.7.7)
|
70
|
+
unicode-display_width (2.0.0)
|
52
71
|
webmock (3.12.2)
|
53
72
|
addressable (>= 2.3.6)
|
54
73
|
crack (>= 0.3.2)
|
@@ -63,6 +82,7 @@ DEPENDENCIES
|
|
63
82
|
mocha
|
64
83
|
pry
|
65
84
|
rake
|
85
|
+
rubocop (~> 1.13.0)
|
66
86
|
webmock
|
67
87
|
|
68
88
|
BUNDLED WITH
|
data/README.md
CHANGED
@@ -65,6 +65,7 @@ faraday = Faraday.new do
|
|
65
65
|
_1.request :url_encoded # auto-encode form bodies
|
66
66
|
_1.response :json # auto-decode JSON responses
|
67
67
|
_1.response :follow_redirects # follow redirects (should be above httpdisk)
|
68
|
+
_1.response :encoding # set Ruby string encoding based on Content-Type (should be above httpdisk)
|
68
69
|
_1.use :httpdisk
|
69
70
|
_1.request :retry # retry failed responses (should be below httpdisk)
|
70
71
|
end
|
@@ -127,6 +128,7 @@ httpdisk supports a few options:
|
|
127
128
|
- `expires_in:` when to expire cached requests, default is nil (never expire)
|
128
129
|
- `force:` don't read anything from cache (but still write)
|
129
130
|
- `force_errors:` don't read errors from cache (but still write)
|
131
|
+
- `logger`: log requests to stderr, or pass your own logger
|
130
132
|
|
131
133
|
Pass these in when setting up Faraday:
|
132
134
|
|
@@ -174,6 +176,10 @@ Specific to httpdisk:
|
|
174
176
|
|
175
177
|
## Changelog
|
176
178
|
|
177
|
-
#### 0.
|
179
|
+
#### 0.2 - May 2020
|
180
|
+
- added `response.env[:httpdisk]`, which will be true if the response came from the cache
|
181
|
+
- `:logger` option
|
182
|
+
- rake rubocop
|
178
183
|
|
184
|
+
#### 0.1 - April 2020
|
179
185
|
- Original release
|
data/Rakefile
CHANGED
@@ -26,6 +26,14 @@ task :pry do
|
|
26
26
|
system 'pry -I lib -r httpdisk.rb'
|
27
27
|
end
|
28
28
|
|
29
|
+
#
|
30
|
+
# rubocop
|
31
|
+
#
|
32
|
+
|
33
|
+
task :rubocop do
|
34
|
+
system('bundle exec rubocop -A .', exception: true)
|
35
|
+
end
|
36
|
+
|
29
37
|
#
|
30
38
|
# gem
|
31
39
|
#
|
@@ -38,7 +46,7 @@ task install: :build do
|
|
38
46
|
system("gem install --quiet httpdisk-#{spec.version}.gem", exception: true)
|
39
47
|
end
|
40
48
|
|
41
|
-
task release:
|
49
|
+
task release: %i[test build] do
|
42
50
|
raise "looks like git isn't clean" unless `git status --porcelain`.empty?
|
43
51
|
|
44
52
|
system("git tag -a #{spec.version} -m 'Tagging #{spec.version}'", exception: true)
|
data/bin/httpdisk
CHANGED
data/examples.rb
CHANGED
@@ -18,7 +18,6 @@ class Examples
|
|
18
18
|
faraday.get('http://www.google.com', nil, { "User-Agent": 'test-agent' })
|
19
19
|
faraday.get('http://www.google.com', { q: 'ruby' })
|
20
20
|
faraday.post('http://httpbin.org/post', 'name=hello')
|
21
|
-
exit
|
22
21
|
|
23
22
|
3.times { puts }
|
24
23
|
response = faraday.get('http://httpbingo.org/get')
|
@@ -106,7 +105,7 @@ class Examples
|
|
106
105
|
end
|
107
106
|
|
108
107
|
3.times { puts }
|
109
|
-
response = faraday.post('http://httpbingo.org/post', { this_is: [
|
108
|
+
response = faraday.post('http://httpbingo.org/post', { this_is: ['json'] })
|
110
109
|
puts response.env.url
|
111
110
|
puts JSON.pretty_generate(response.body)
|
112
111
|
end
|
data/httpdisk.gemspec
CHANGED
@@ -3,7 +3,7 @@ require_relative 'lib/httpdisk/version'
|
|
3
3
|
Gem::Specification.new do |s|
|
4
4
|
s.name = 'httpdisk'
|
5
5
|
s.version = HTTPDisk::VERSION
|
6
|
-
s.authors = [
|
6
|
+
s.authors = ['Adam Doppelt']
|
7
7
|
s.email = 'amd@gurge.com'
|
8
8
|
|
9
9
|
s.summary = 'httpdisk - disk cache for faraday'
|
@@ -18,7 +18,7 @@ Gem::Specification.new do |s|
|
|
18
18
|
end
|
19
19
|
s.bindir = 'bin'
|
20
20
|
s.executables = s.files.grep(%r{^#{s.bindir}/}) { File.basename(_1) }
|
21
|
-
s.require_paths = [
|
21
|
+
s.require_paths = ['lib']
|
22
22
|
|
23
23
|
# gem dependencies
|
24
24
|
s.add_dependency 'faraday', '~> 1.4'
|
data/lib/httpdisk/cache.rb
CHANGED
@@ -15,9 +15,10 @@ module HTTPDisk
|
|
15
15
|
if expires_in && !expires_in.is_a?(Integer)
|
16
16
|
raise ArgumentError, "expected :expires_in to be an integer, not #{expires_in.inspect}"
|
17
17
|
end
|
18
|
+
|
18
19
|
%i[force force_errors].each do
|
19
20
|
value = send(_1)
|
20
|
-
if ![
|
21
|
+
if ![nil, true, false].include?(value)
|
21
22
|
raise ArgumentError, "expected #{_1} to be a boolean, not #{value.inspect}"
|
22
23
|
end
|
23
24
|
end
|
@@ -39,8 +40,9 @@ module HTTPDisk
|
|
39
40
|
|
40
41
|
# Cache status for a cache_key, %i[error force hit miss stale]
|
41
42
|
def status(cache_key)
|
42
|
-
payload_or_status = read0(cache_key)
|
43
|
+
payload_or_status = read0(cache_key, peek: true)
|
43
44
|
return payload_or_status if payload_or_status.is_a?(Symbol)
|
45
|
+
|
44
46
|
payload_or_status.error_999? ? :error : :hit
|
45
47
|
end
|
46
48
|
|
@@ -59,14 +61,14 @@ module HTTPDisk
|
|
59
61
|
protected
|
60
62
|
|
61
63
|
# low level read, returns payload or status
|
62
|
-
def read0(cache_key)
|
64
|
+
def read0(cache_key, peek: false)
|
63
65
|
path = diskpath(cache_key)
|
64
66
|
|
65
67
|
return :miss if !File.exist?(path)
|
66
68
|
return :stale if expired?(path)
|
67
69
|
return :force if force?
|
68
70
|
|
69
|
-
payload = Zlib::GzipReader.open(path) { Payload.read(_1) }
|
71
|
+
payload = Zlib::GzipReader.open(path) { Payload.read(_1, peek: peek) }
|
70
72
|
return :force if force_errors? && payload.error_999?
|
71
73
|
|
72
74
|
payload
|
data/lib/httpdisk/cache_key.rb
CHANGED
@@ -68,10 +68,9 @@ module HTTPDisk
|
|
68
68
|
# Calculate cache key segment for body
|
69
69
|
def bodykey
|
70
70
|
body = env.request_body.to_s
|
71
|
-
|
72
|
-
when env.request_headers['Content-Type'] == 'application/x-www-form-urlencoded'
|
71
|
+
if env.request_headers['Content-Type'] == 'application/x-www-form-urlencoded'
|
73
72
|
querykey(body)
|
74
|
-
|
73
|
+
elsif body.length < 50
|
75
74
|
body
|
76
75
|
else
|
77
76
|
Digest::MD5.hexdigest(body)
|
data/lib/httpdisk/cli.rb
CHANGED
@@ -119,6 +119,7 @@ module HTTPDisk
|
|
119
119
|
if !Faraday::Connection::METHODS.include?(method)
|
120
120
|
raise CliError, "invalid --request #{method.inspect}"
|
121
121
|
end
|
122
|
+
|
122
123
|
method
|
123
124
|
end
|
124
125
|
|
@@ -130,6 +131,7 @@ module HTTPDisk
|
|
130
131
|
if url =~ %r{^\w+://}
|
131
132
|
raise CliError, 'only http/https supported'
|
132
133
|
end
|
134
|
+
|
133
135
|
url = "http://#{url}"
|
134
136
|
end
|
135
137
|
URI.parse(url)
|
@@ -154,6 +156,7 @@ module HTTPDisk
|
|
154
156
|
if !key || !value || key.empty? || value.empty?
|
155
157
|
raise CliError, "invalid --header #{header.inspect}"
|
156
158
|
end
|
159
|
+
|
157
160
|
headers[key] = value
|
158
161
|
end
|
159
162
|
end
|
@@ -172,6 +175,7 @@ module HTTPDisk
|
|
172
175
|
if !seconds
|
173
176
|
raise CliError, "invalid --expires #{options[:expires].inspect}"
|
174
177
|
end
|
178
|
+
|
175
179
|
client_options[:expires_in] = seconds
|
176
180
|
end
|
177
181
|
client_options[:force] = options[:force]
|
@@ -185,6 +189,7 @@ module HTTPDisk
|
|
185
189
|
|
186
190
|
proxy = parse_proxy(options[:proxy])
|
187
191
|
raise CliError, "--proxy should be host[:port], not #{options[:proxy].inspect}" if !proxy
|
192
|
+
|
188
193
|
proxy
|
189
194
|
end
|
190
195
|
|
data/lib/httpdisk/client.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'faraday'
|
2
|
+
require 'logger'
|
2
3
|
|
3
4
|
module HTTPDisk
|
4
5
|
OPTIONS = {
|
@@ -6,6 +7,7 @@ module HTTPDisk
|
|
6
7
|
expires_in: nil,
|
7
8
|
force: false,
|
8
9
|
force_errors: false,
|
10
|
+
logger: false,
|
9
11
|
}.freeze
|
10
12
|
|
11
13
|
# Middleware and main entry point.
|
@@ -19,14 +21,16 @@ module HTTPDisk
|
|
19
21
|
|
20
22
|
def call(env)
|
21
23
|
cache_key = CacheKey.new(env)
|
24
|
+
logger&.info("#{env.method.upcase} #{env.url} (#{cache.status(cache_key)})")
|
22
25
|
|
23
|
-
# hit?
|
24
26
|
if cached_response = read(cache_key, env)
|
27
|
+
cached_response.env[:httpdisk] = true
|
25
28
|
return cached_response
|
26
29
|
end
|
27
30
|
|
28
31
|
# miss
|
29
|
-
perform(
|
32
|
+
perform(env).tap do |response|
|
33
|
+
response.env[:httpdisk] = false
|
30
34
|
write(cache_key, env, response)
|
31
35
|
end
|
32
36
|
end
|
@@ -46,7 +50,7 @@ module HTTPDisk
|
|
46
50
|
protected
|
47
51
|
|
48
52
|
# perform the request, return Faraday::Response
|
49
|
-
def perform(
|
53
|
+
def perform(env)
|
50
54
|
app.call(env)
|
51
55
|
rescue Faraday::ConnectionFailed, Faraday::SSLError, Faraday::TimeoutError => e
|
52
56
|
# try to avoid caching proxy errors
|
@@ -95,6 +99,15 @@ module HTTPDisk
|
|
95
99
|
|
96
100
|
err.to_s =~ /#{proxy.host}.*#{proxy.port}/
|
97
101
|
end
|
102
|
+
|
103
|
+
def logger
|
104
|
+
return @logger if defined?(@logger)
|
105
|
+
|
106
|
+
@logger = case options[:logger]
|
107
|
+
when true then Logger.new($stderr)
|
108
|
+
when Logger then options[:logger]
|
109
|
+
end
|
110
|
+
end
|
98
111
|
end
|
99
112
|
end
|
100
113
|
|
data/lib/httpdisk/payload.rb
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
module HTTPDisk
|
2
2
|
class Payload
|
3
3
|
class << self
|
4
|
-
def read(f)
|
4
|
+
def read(f, peek: false)
|
5
5
|
Payload.new.tap do |p|
|
6
6
|
# comment
|
7
7
|
p.comment = f.gets[/^# (.*)/, 1]
|
8
8
|
|
9
9
|
# status line
|
10
|
-
m = f.gets.match(
|
10
|
+
m = f.gets.match(/^HTTPDISK (\d+) (.*)$/)
|
11
11
|
p.status, p.reason_phrase = m[1].to_i, m[2]
|
12
12
|
|
13
13
|
# headers
|
@@ -16,8 +16,8 @@ module HTTPDisk
|
|
16
16
|
p.headers[key] = value
|
17
17
|
end
|
18
18
|
|
19
|
-
# body
|
20
|
-
p.body = f.read
|
19
|
+
# body (if not peeking)
|
20
|
+
p.body = f.read if !peek
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/httpdisk/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: httpdisk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Doppelt
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-05-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: faraday
|
@@ -75,6 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- ".github/workflows/test.yml"
|
77
77
|
- ".gitignore"
|
78
|
+
- ".rubocop.yml"
|
78
79
|
- Gemfile
|
79
80
|
- Gemfile.lock
|
80
81
|
- LICENSE
|