statica 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +4 -0
- data/README.md +10 -15
- data/lib/statica.rb +46 -3
- data/test/test_statica.rb +2 -2
- metadata +3 -2
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -2,36 +2,31 @@
|
|
2
2
|
|
3
3
|
Statica is a static asset caching solution.
|
4
4
|
|
5
|
-
#
|
5
|
+
# About
|
6
6
|
|
7
|
-
|
7
|
+
Statica provides a simple solution for generating cache bursting urls for your static resources.
|
8
8
|
|
9
|
-
|
9
|
+
# Considerations/Goals
|
10
10
|
|
11
|
-
*
|
12
|
-
*
|
13
|
-
*
|
11
|
+
* Acheive longer cache life for your resources by generating a per asset digest
|
12
|
+
* No file name modifications in order to maintain revision history
|
13
|
+
* Do not use a query parameter since they are ignored by some mechanisms
|
14
|
+
* Provide simple Rack middleware to remove the digest and process the asset as normal
|
14
15
|
|
15
|
-
# Synopsis
|
16
16
|
|
17
|
-
|
17
|
+
# HowTo
|
18
18
|
|
19
|
-
In order to achieve
|
19
|
+
In order to achieve the above goals, Statica takes the simple approach of appending the hex digest to the end of the static asset path like so:
|
20
20
|
|
21
21
|
> Statica.digest_url("/javascripts/application.js")
|
22
22
|
=>"/javascripts/application.js/d79dbf6e6c051b22f1ab91fec4cf81855883cc7d0a3f3e242b56b97fbcd756cb"
|
23
23
|
|
24
|
-
Notice how the file name does not change. We are simply appending a qualifier to the resource for caching. In order to serve the asset, Statica comes with Rack middleware that simply removes the digest portion allowing your application to serve the asset as normal.
|
24
|
+
Notice how the file name does not change. We are simply appending a qualifier to the resource for caching without using a query parameter. In order to serve the asset, Statica comes with Rack middleware that simply removes the digest portion allowing your application to serve the asset as normal.
|
25
25
|
|
26
|
-
# If Statica path, remove the digest portion, allow app to serve normally
|
27
26
|
use Rack::StaticaServer
|
28
27
|
|
29
28
|
If you use an HTTP Server like [Apache](http://httpd.apache.org/) or [Nginx](http://wiki.nginx.org/Main) you can setup rules to ignore the digest and server the asset. I'll post sample rules here later.
|
30
29
|
|
31
|
-
# About
|
32
|
-
|
33
|
-
More to come...
|
34
|
-
|
35
30
|
# Acknowledgement
|
36
31
|
|
37
32
|
Huge thanks to my company, [Primedia](http://primedia.com) for encouraging open source contributions.
|
data/lib/statica.rb
CHANGED
@@ -5,46 +5,89 @@ module Statica
|
|
5
5
|
|
6
6
|
# Statica version string
|
7
7
|
# @api public
|
8
|
-
VERSION = '0.
|
8
|
+
VERSION = '0.3.0'
|
9
9
|
|
10
10
|
extend self
|
11
11
|
|
12
|
-
# Fully qualified path to the root directory
|
12
|
+
# Fully qualified path to the root directory of the static assets
|
13
13
|
attr_accessor :root_dir
|
14
14
|
|
15
|
+
# Set digest class
|
16
|
+
#
|
17
|
+
# @param [Digest::Base] klass Digest::Base implementation
|
15
18
|
def digest_class=(klass)
|
16
19
|
@digest = klass
|
17
20
|
end
|
18
21
|
|
22
|
+
# Current digest
|
23
|
+
#
|
24
|
+
# @return [Digest::Base] Digest::Base implementation instance
|
19
25
|
def digest
|
20
26
|
(@digest || ::Digest::SHA256).new
|
21
27
|
end
|
22
28
|
|
29
|
+
# Current cache
|
30
|
+
#
|
31
|
+
# @return [Hash] Current cached_digest hash; initializes to empty hash
|
32
|
+
def cached_digest
|
33
|
+
@cached_digest ||= {}
|
34
|
+
end
|
35
|
+
|
36
|
+
# Reset cached digest to new hash
|
37
|
+
#
|
38
|
+
# @return [Hash] Current cached_digest initialized to empty hash
|
39
|
+
def reset_cached_digest
|
40
|
+
@cached_digest = {}
|
41
|
+
end
|
42
|
+
|
43
|
+
# List of subdirectories where static resources are held
|
44
|
+
#
|
45
|
+
# @return [Array] Initialized to the default values of: javascripts stylesheets images js css
|
23
46
|
def sub_dirs
|
24
47
|
@sub_dirs ||= %w{javascripts stylesheets images js css}
|
25
48
|
end
|
26
49
|
|
50
|
+
# Set the subdirectories if the default values don't suffice
|
51
|
+
#
|
52
|
+
# @param [Array] Subdirectories where static assets are stored
|
53
|
+
# @return [Array] Newly initialized sub_dirs array
|
27
54
|
def sub_dirs=(array)
|
28
55
|
@sub_dirs = array
|
29
56
|
end
|
30
57
|
|
58
|
+
# Calculate the hex digest for the given resource
|
59
|
+
#
|
60
|
+
# @param [String] Typically a resource such as /js/application.js or /css/home-style.css
|
61
|
+
# @return [String] Digest calculated on the contents of the path
|
31
62
|
def digest_for(path)
|
63
|
+
return cached_digest[path] if cached_digest.has_key?(path)
|
32
64
|
path.chop! if path.end_with?("/")
|
33
65
|
fname = File.join(root_dir, path)
|
34
66
|
|
35
67
|
raise ResourceNotFoundError, "#{fname} not found!" unless File.exist?(fname)
|
36
68
|
|
37
|
-
digest.file(fname).hexdigest
|
69
|
+
cached_digest[path] = digest.file(fname).hexdigest
|
38
70
|
end
|
39
71
|
|
72
|
+
# Append digest to url
|
73
|
+
#
|
74
|
+
# @param [String] Typically a resource such as /js/application.js or /css/home-style.css
|
75
|
+
# @return [String] Path + Digest calculated on the contents of the path
|
40
76
|
def digest_url(url)
|
41
77
|
"#{url}/#{digest_for(url)}"
|
42
78
|
end
|
43
79
|
|
80
|
+
# If path is a digest_url, remove the digest portion.
|
81
|
+
#
|
82
|
+
# @param [String] Static resource path
|
83
|
+
# @return [String] Original path if regex did not match; Path without digest on regex match
|
44
84
|
def resolve(path)
|
45
85
|
(path =~ regex) ? path.sub($2, '') : path
|
46
86
|
end
|
47
87
|
|
88
|
+
# Regex to determine if path is a Static generated path with digest
|
89
|
+
#
|
90
|
+
# @return [Regex] instance
|
48
91
|
def regex
|
49
92
|
leaders = sub_dirs.collect{|t| Regexp.escape(t)}.join("|")
|
50
93
|
@regex ||= /\A\/?(#{leaders})\S*(\/[a-z0-9]+\/?)\Z/
|
data/test/test_statica.rb
CHANGED
@@ -8,7 +8,7 @@ class TestStatica < TestBase
|
|
8
8
|
end
|
9
9
|
end
|
10
10
|
|
11
|
-
def
|
11
|
+
def test_digests_are_cached
|
12
12
|
digest1 = ''
|
13
13
|
digest2 = ''
|
14
14
|
|
@@ -17,7 +17,7 @@ class TestStatica < TestBase
|
|
17
17
|
R.test_file(path){ |f| digest1 = Statica.digest_for(path) }
|
18
18
|
R.test_file(path){ |f| digest2 = Statica.digest_for(path) }
|
19
19
|
|
20
|
-
|
20
|
+
assert_equal digest1, digest2
|
21
21
|
end
|
22
22
|
|
23
23
|
def test_digest_path_format
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: statica
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2011-12-
|
12
|
+
date: 2011-12-27 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description:
|
15
15
|
email:
|
@@ -54,3 +54,4 @@ signing_key:
|
|
54
54
|
specification_version: 3
|
55
55
|
summary: Statica is a static asset caching solution.
|
56
56
|
test_files: []
|
57
|
+
has_rdoc:
|