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.
@@ -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.
@@ -0,0 +1,13 @@
1
+ require 'rake/testtask'
2
+ require 'bundler'
3
+
4
+ desc "Run tests"
5
+ task :default => [:test]
6
+
7
+ Rake::TestTask.new do |t|
8
+ t.warning = true
9
+ t.verbose = true
10
+ t.test_files = FileList['spec/*_spec.rb']
11
+ end
12
+
13
+ Bundler::GemHelper.install_tasks
@@ -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