rack-digestif 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.
- data/MIT-LICENSE +20 -0
- data/Rakefile +13 -0
- data/Readme.md +52 -0
- data/lib/rack/digestif.rb +16 -0
- data/rack-digestif.gemspec +21 -0
- data/spec/rack_digestif_spec.rb +34 -0
- metadata +87 -0
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Tim Lucas
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
data/Readme.md
ADDED
@@ -0,0 +1,52 @@
|
|
1
|
+
Rack::Digestif
|
2
|
+
==============
|
3
|
+
|
4
|
+
A rack middleware that ensures Sprockets assets are served regardless of whether the asset digest matches.
|
5
|
+
|
6
|
+
All asset URLs such as:
|
7
|
+
|
8
|
+
/assets/application-a1d0c6e83f027327d8461063f4ac58a6.css
|
9
|
+
|
10
|
+
are rewritten to remove the digest:
|
11
|
+
|
12
|
+
/assets/application.css
|
13
|
+
|
14
|
+
This works thanks to Sprockets compiling both digest and non-digest filenames in the assets directory.
|
15
|
+
|
16
|
+
Why?
|
17
|
+
----
|
18
|
+
|
19
|
+
Sprockets (and the Rails asset pipeline) use MD5 hashes of files to create cache-busting URLs. These new URLs have one big disadvantage over the old query-string method: requests to assets with an out-of-date digest cause a 404, unlike the old method which would serve the asset file regardless of the correctness of the timestamp. This problem becomes particularly noticable during a deployment when a browser requests an asset but the digest has been updated on the server and so they receive a 404, resulting in an unstyled or javascript-less page.
|
20
|
+
|
21
|
+
Luckily the fix is easy; Sprockets generates every compiled file with and without a digest, so all that's needed is to rewrite incoming requests to remove the digest from the path. You can do this in nginx or HTTP proxy, rack-rewrite, or using `Rack::Digestif`.
|
22
|
+
|
23
|
+
Installation
|
24
|
+
------------
|
25
|
+
|
26
|
+
$ gem install rack-digestif
|
27
|
+
|
28
|
+
Usage
|
29
|
+
-----
|
30
|
+
|
31
|
+
Add it to your Rackup `config.ru` file like so:
|
32
|
+
|
33
|
+
require 'rack/digestif'
|
34
|
+
use Rack::Digestif
|
35
|
+
|
36
|
+
By default `Rack::Digestif` will rewrite all incoming URLs that have a digest. If you want to limit it to a given path, such as `/assets`, you simply pass the path as the first argument:
|
37
|
+
|
38
|
+
use Rack::Digestif, "/assets/"
|
39
|
+
|
40
|
+
|
41
|
+
Rails Usage
|
42
|
+
-----------
|
43
|
+
|
44
|
+
Firstly add it to your `Gemfile`, and then add the middleware in `application.rb` like so:
|
45
|
+
|
46
|
+
config.middleware.insert_before ActionDispatch::Static, Rack::Digestif
|
47
|
+
|
48
|
+
|
49
|
+
License
|
50
|
+
-------
|
51
|
+
|
52
|
+
See MIT-LICENSE for details.
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module Rack
|
2
|
+
# Rack middleware which rewrites the REQUEST_PATH to remove the asset digest
|
3
|
+
class Digestif
|
4
|
+
PATTERN = /-[0-9a-z]{32}(\.[^.]+)\Z/.freeze
|
5
|
+
def initialize app, path=nil
|
6
|
+
@app = app
|
7
|
+
@path = path.freeze
|
8
|
+
end
|
9
|
+
def call env
|
10
|
+
if (not @path) || (@path && env["PATH_INFO"].index(@path) == 0)
|
11
|
+
env["PATH_INFO"].gsub! PATTERN, '\1'
|
12
|
+
end
|
13
|
+
@app.call env
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'rack-digestif'
|
3
|
+
s.version = '0.1'
|
4
|
+
|
5
|
+
s.summary = "A rack middleware that ensures Sprockets assets are served regardless of whether the asset digest matches"
|
6
|
+
s.description = s.summary
|
7
|
+
|
8
|
+
s.author = 'Tim Lucas'
|
9
|
+
s.email = 't@toolmantim.com'
|
10
|
+
s.homepage = 'http://github.com/toolmantim/rack-digestif'
|
11
|
+
|
12
|
+
s.files = Dir['Readme.md', 'MIT-LICENSE', 'Rakefile', 'rack-digestif.gemspec', 'lib/**/*']
|
13
|
+
s.test_files = Dir['spec/*']
|
14
|
+
s.require_path = 'lib'
|
15
|
+
s.requirements << 'none'
|
16
|
+
|
17
|
+
s.add_dependency 'rack'
|
18
|
+
|
19
|
+
s.add_development_dependency "minitest"
|
20
|
+
s.add_development_dependency "bundler"
|
21
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
|
3
|
+
require 'rack/digestif'
|
4
|
+
require 'rack/mock'
|
5
|
+
|
6
|
+
describe Rack::Digestif do
|
7
|
+
|
8
|
+
let(:base_app) { Proc.new {|env| [200, {}, Rack::Request.new(env).path]} }
|
9
|
+
|
10
|
+
def path_after_digestif request_path
|
11
|
+
Rack::MockRequest.new(app).get(request_path).body
|
12
|
+
end
|
13
|
+
|
14
|
+
describe "initialized no arguments" do
|
15
|
+
let(:app) { Rack::Digestif.new(base_app) }
|
16
|
+
it "must rewrite assets with digests" do
|
17
|
+
path_after_digestif("/path/f-c20ad4d76fe97759aa27a0c99bff6710.css").must_equal "/path/f.css"
|
18
|
+
end
|
19
|
+
it "mustn't rewrite assets without digests" do
|
20
|
+
path_after_digestif("/path/f.css").must_equal "/path/f.css"
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "initialized with a path argument" do
|
25
|
+
let(:app) { Rack::Digestif.new(base_app, "/custom-path/") }
|
26
|
+
it "must rewrite assets with digests in the custom path" do
|
27
|
+
path_after_digestif("/custom-path/f-c20ad4d76fe97759aa27a0c99bff6710.css").must_equal "/custom-path/f.css"
|
28
|
+
end
|
29
|
+
it "mustn't rewrite assets with digests outside the custom path" do
|
30
|
+
path_after_digestif("/other-path/f-c20ad4d76fe97759aa27a0c99bff6710.css").must_equal "/other-path/f-c20ad4d76fe97759aa27a0c99bff6710.css"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,87 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: rack-digestif
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tim Lucas
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-03-04 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rack
|
16
|
+
requirement: &70284270993820 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70284270993820
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: minitest
|
27
|
+
requirement: &70284270993140 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70284270993140
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: bundler
|
38
|
+
requirement: &70284270990840 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ! '>='
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '0'
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70284270990840
|
47
|
+
description: A rack middleware that ensures Sprockets assets are served regardless
|
48
|
+
of whether the asset digest matches
|
49
|
+
email: t@toolmantim.com
|
50
|
+
executables: []
|
51
|
+
extensions: []
|
52
|
+
extra_rdoc_files: []
|
53
|
+
files:
|
54
|
+
- Readme.md
|
55
|
+
- MIT-LICENSE
|
56
|
+
- Rakefile
|
57
|
+
- rack-digestif.gemspec
|
58
|
+
- lib/rack/digestif.rb
|
59
|
+
- spec/rack_digestif_spec.rb
|
60
|
+
homepage: http://github.com/toolmantim/rack-digestif
|
61
|
+
licenses: []
|
62
|
+
post_install_message:
|
63
|
+
rdoc_options: []
|
64
|
+
require_paths:
|
65
|
+
- lib
|
66
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
67
|
+
none: false
|
68
|
+
requirements:
|
69
|
+
- - ! '>='
|
70
|
+
- !ruby/object:Gem::Version
|
71
|
+
version: '0'
|
72
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
requirements:
|
79
|
+
- none
|
80
|
+
rubyforge_project:
|
81
|
+
rubygems_version: 1.8.11
|
82
|
+
signing_key:
|
83
|
+
specification_version: 3
|
84
|
+
summary: A rack middleware that ensures Sprockets assets are served regardless of
|
85
|
+
whether the asset digest matches
|
86
|
+
test_files:
|
87
|
+
- spec/rack_digestif_spec.rb
|