roda 3.103.0 → 3.104.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/lib/roda/plugins/hash_public.rb +31 -11
- data/lib/roda/plugins/hash_public_cache.rb +91 -0
- data/lib/roda/plugins/json.rb +4 -2
- data/lib/roda/plugins/timestamp_public.rb +5 -2
- data/lib/roda/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: 7ea3b3c7c8ffcfffa22412e123d09e718e876c13bdfcddbfae461daa813d81bd
|
|
4
|
+
data.tar.gz: 275d90d97fa2893654e368316c1233092ae5fcd60ac7e76ac026a45d2200582b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 546ee3b7cb9d6c8eac9eb6bbc40272a1a5760f522bbe94b38bb78afa3f552a61dd23496d2dfcf4e65fe490b1cad67b229fed4c31ac22b9d25409e501f6bb5c82
|
|
7
|
+
data.tar.gz: f9e94f7612706155c60db6f9a14bb9b130386875f1c86e6a65bc29bf9fdb789719c08f5398f58708ac862ab8b3ec41fb34f11b21d7454878be4364fceb50ce91
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
# frozen-string-literal: true
|
|
2
2
|
|
|
3
|
-
require 'digest/sha2'
|
|
4
|
-
|
|
5
3
|
class Roda
|
|
6
4
|
module RodaPlugins
|
|
7
5
|
# The hash_public plugin adds a +hash_path+ method for constructing
|
|
@@ -26,7 +24,9 @@ class Roda
|
|
|
26
24
|
# This plugin caches the digest of file content on first read. That means
|
|
27
25
|
# if you change the file after that, it will continue to show the old hash.
|
|
28
26
|
# This can cause problems in development mode if you are modifying the
|
|
29
|
-
# content of files served by the plugin.
|
|
27
|
+
# content of files served by the plugin. You can use the hash_public_cache
|
|
28
|
+
# plugin to scan the public directory in and store the digests in a file,
|
|
29
|
+
# avoiding the need for the process to read files to calculate the digest.
|
|
30
30
|
#
|
|
31
31
|
# Examples:
|
|
32
32
|
#
|
|
@@ -48,6 +48,20 @@ class Roda
|
|
|
48
48
|
# end
|
|
49
49
|
# end
|
|
50
50
|
module HashPublic
|
|
51
|
+
Digest = begin
|
|
52
|
+
require 'openssl'
|
|
53
|
+
::OpenSSL::Digest
|
|
54
|
+
# :nocov:
|
|
55
|
+
rescue LoadError
|
|
56
|
+
require 'digest/sha2'
|
|
57
|
+
::Digest
|
|
58
|
+
# :nocov:
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def self.load_dependencies(app, opts = OPTS)
|
|
62
|
+
app.plugin :public, opts
|
|
63
|
+
end
|
|
64
|
+
|
|
51
65
|
# Use options given to setup content-hash-based file serving. The
|
|
52
66
|
# following options are recognized by the plugin:
|
|
53
67
|
#
|
|
@@ -57,23 +71,20 @@ class Roda
|
|
|
57
71
|
#
|
|
58
72
|
# The options given are also passed to the public plugin.
|
|
59
73
|
def self.configure(app, opts = {})
|
|
60
|
-
app.plugin :public, opts
|
|
61
74
|
app.opts[:hash_public_prefix] = (opts[:prefix] || app.opts[:hash_public_prefix] || 'static').dup.freeze
|
|
62
75
|
app.opts[:hash_public_length] = opts[:length] || app.opts[:hash_public_length]
|
|
63
76
|
app.opts[:hash_public_mutex] ||= Mutex.new
|
|
64
77
|
app.opts[:hash_public_cache] ||= {}
|
|
65
78
|
end
|
|
66
79
|
|
|
67
|
-
module
|
|
68
|
-
#
|
|
69
|
-
|
|
70
|
-
# reasons, so this should not be called with untrusted input.
|
|
71
|
-
def hash_path(file)
|
|
80
|
+
module ClassMethods
|
|
81
|
+
# The digest for the given file to use in hash_path.
|
|
82
|
+
def hash_path_digest(file)
|
|
72
83
|
opts = self.opts
|
|
73
84
|
cache = opts[:hash_public_cache]
|
|
74
85
|
mutex = opts[:hash_public_mutex]
|
|
75
86
|
unless digest = mutex.synchronize{cache[file]}
|
|
76
|
-
digest =
|
|
87
|
+
digest = Digest::SHA256.file(File.join(opts[:public_root], file)).base64digest
|
|
77
88
|
digest.chomp!("=")
|
|
78
89
|
digest.tr!("+/", "-_")
|
|
79
90
|
if length = opts[:hash_public_length]
|
|
@@ -82,7 +93,16 @@ class Roda
|
|
|
82
93
|
digest.freeze
|
|
83
94
|
mutex.synchronize{cache[file] = digest}
|
|
84
95
|
end
|
|
85
|
-
|
|
96
|
+
digest
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
module InstanceMethods
|
|
101
|
+
# Return a path to the static file that could be served by r.hash_public.
|
|
102
|
+
# This does not check the file is inside the directory for performance
|
|
103
|
+
# reasons, so this should not be called with untrusted input.
|
|
104
|
+
def hash_path(file)
|
|
105
|
+
"/#{opts[:hash_public_prefix]}/#{self.class.hash_path_digest(file)}/#{file}"
|
|
86
106
|
end
|
|
87
107
|
end
|
|
88
108
|
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
# frozen-string-literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'find'
|
|
5
|
+
|
|
6
|
+
class Roda
|
|
7
|
+
module RodaPlugins
|
|
8
|
+
# The hash_public_cache plugin builds on top of the hash_public plugin and
|
|
9
|
+
# adds the ability to store the digests for the public files in a json file,
|
|
10
|
+
# and load that file at startup, which avoids the need for the process to
|
|
11
|
+
# read the public file in order to compute the digest.
|
|
12
|
+
#
|
|
13
|
+
# Examples:
|
|
14
|
+
#
|
|
15
|
+
# # Load the plugin. Options given will be passed to public and hash_public.
|
|
16
|
+
# plugin :hash_public_cache, "path/to/cache_file.json"
|
|
17
|
+
#
|
|
18
|
+
# # When rebuilding the cache:
|
|
19
|
+
# #
|
|
20
|
+
# # * Scan the public directory for files, calculate the digest on each.
|
|
21
|
+
# # * Write the hash public cache to a file.
|
|
22
|
+
# #
|
|
23
|
+
# # This is split into separate steps in case you want to modify the cache
|
|
24
|
+
# # manually after the scan.
|
|
25
|
+
# scan_hash_public_cache_dir
|
|
26
|
+
# dump_hash_public_cache_file
|
|
27
|
+
#
|
|
28
|
+
# # To load the cache at application startup (if the file exists):
|
|
29
|
+
# load_hash_public_cache_file
|
|
30
|
+
module HashPublicCache
|
|
31
|
+
def self.load_dependencies(app, _cache_file, opts = OPTS)
|
|
32
|
+
app.plugin :hash_public, opts
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Specify the location of the hash public cache file.
|
|
36
|
+
#
|
|
37
|
+
# The options given are passed to the hash_public plugin.
|
|
38
|
+
def self.configure(app, cache_file, opts = OPTS)
|
|
39
|
+
app.opts[:hash_public_cache_file] = cache_file
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
module ClassMethods
|
|
43
|
+
# Load the hash public cache file, if it exists. This replaces the hash
|
|
44
|
+
# public cache with the values from the file.
|
|
45
|
+
def load_hash_public_cache_file
|
|
46
|
+
file = opts[:hash_public_cache_file]
|
|
47
|
+
return unless File.file?(file)
|
|
48
|
+
|
|
49
|
+
cache = opts[:hash_public_cache] = (opts[:json_parser] || ::JSON.method(:parse)).call(::File.read(file))
|
|
50
|
+
cache.each_value(&:freeze)
|
|
51
|
+
nil
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Scan the public directory for files, computing the hash public digest
|
|
55
|
+
# for each. This will not rescan files that already have digest values.
|
|
56
|
+
# If a block is given, it will only calculate the digest for the file
|
|
57
|
+
# if the block returns truthy.
|
|
58
|
+
def scan_hash_public_cache_dir
|
|
59
|
+
cache = opts[:hash_public_cache]
|
|
60
|
+
|
|
61
|
+
# Public root doesn't have trailing slash even if given, as
|
|
62
|
+
# File.expand_path removes it.
|
|
63
|
+
root = opts[:public_root] + File::SEPARATOR
|
|
64
|
+
|
|
65
|
+
Find.find(opts[:public_root]) do |file|
|
|
66
|
+
if File.file?(file)
|
|
67
|
+
file = file.sub(root, '')
|
|
68
|
+
next if cache[file]
|
|
69
|
+
|
|
70
|
+
if defined?(yield)
|
|
71
|
+
next unless yield file
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
cache[file] = hash_path_digest(file)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
nil
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
# Write the current hash public cache to the cache file.
|
|
82
|
+
def dump_hash_public_cache_file
|
|
83
|
+
File.write(opts[:hash_public_cache_file], (opts[:json_serializer] || :to_json.to_proc).call(opts[:hash_public_cache]))
|
|
84
|
+
nil
|
|
85
|
+
end
|
|
86
|
+
end
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
register_plugin(:hash_public_cache, HashPublicCache)
|
|
90
|
+
end
|
|
91
|
+
end
|
data/lib/roda/plugins/json.rb
CHANGED
|
@@ -56,10 +56,12 @@ class Roda
|
|
|
56
56
|
# This plugin depends on the custom_block_results plugin, and therefore does
|
|
57
57
|
# not support treating String, FalseClass, or NilClass values as JSON.
|
|
58
58
|
module Json
|
|
59
|
-
|
|
60
|
-
def self.configure(app, opts=OPTS)
|
|
59
|
+
def self.load_dependencies(app, opts=OPTS)
|
|
61
60
|
app.plugin :custom_block_results
|
|
61
|
+
end
|
|
62
62
|
|
|
63
|
+
# Set the classes to automatically convert to JSON, and the serializer to use.
|
|
64
|
+
def self.configure(app, opts=OPTS)
|
|
63
65
|
classes = opts[:classes] || [Array, Hash]
|
|
64
66
|
app.opts[:json_result_classes] ||= []
|
|
65
67
|
app.opts[:json_result_classes] += classes
|
|
@@ -35,14 +35,17 @@ class Roda
|
|
|
35
35
|
# end
|
|
36
36
|
# end
|
|
37
37
|
module TimestampPublic
|
|
38
|
+
def self.load_dependencies(app, opts=OPTS)
|
|
39
|
+
app.plugin :public, opts
|
|
40
|
+
end
|
|
41
|
+
|
|
38
42
|
# Use options given to setup timestamped file serving. The following option is
|
|
39
43
|
# recognized by the plugin:
|
|
40
44
|
#
|
|
41
45
|
# :prefix :: The prefix for paths, before the timestamp segment
|
|
42
46
|
#
|
|
43
47
|
# The options given are also passed to the public plugin.
|
|
44
|
-
def self.configure(app, opts=
|
|
45
|
-
app.plugin :public, opts
|
|
48
|
+
def self.configure(app, opts=OPTS)
|
|
46
49
|
app.opts[:timestamp_public_prefix] = (opts[:prefix] || app.opts[:timestamp_public_prefix] || "static").dup.freeze
|
|
47
50
|
end
|
|
48
51
|
|
data/lib/roda/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: roda
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 3.
|
|
4
|
+
version: 3.104.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jeremy Evans
|
|
@@ -219,6 +219,7 @@ files:
|
|
|
219
219
|
- lib/roda/plugins/hash_matcher.rb
|
|
220
220
|
- lib/roda/plugins/hash_paths.rb
|
|
221
221
|
- lib/roda/plugins/hash_public.rb
|
|
222
|
+
- lib/roda/plugins/hash_public_cache.rb
|
|
222
223
|
- lib/roda/plugins/hash_routes.rb
|
|
223
224
|
- lib/roda/plugins/head.rb
|
|
224
225
|
- lib/roda/plugins/header_matchers.rb
|
|
@@ -337,7 +338,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
337
338
|
- !ruby/object:Gem::Version
|
|
338
339
|
version: '0'
|
|
339
340
|
requirements: []
|
|
340
|
-
rubygems_version: 4.0.
|
|
341
|
+
rubygems_version: 4.0.10
|
|
341
342
|
specification_version: 4
|
|
342
343
|
summary: Routing tree web toolkit
|
|
343
344
|
test_files: []
|