rack-zippy 0.1.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ ## 1.0.0 / 2013-08-22
2
+
3
+ Production-ready release
4
+
5
+ - Only set years-old cache-friendly last-modified header on assets with max-age of at least 1 month
6
+
1
7
  ## 0.1.0 / 2013-08-21
2
8
 
3
- Initial release
9
+ Initial release
data/README.md CHANGED
@@ -37,3 +37,11 @@ application's public/ directory and will respond with sensible caching headers.
37
37
  4. Push to the branch (`git push origin my-new-feature`)
38
38
  5. Create new Pull Request
39
39
 
40
+ ## Releasing a new gem
41
+
42
+ 1. Increment version in lib/rack-zippy/version.rb in line with semantic versioning
43
+ 2. Update CHANGELOG.md
44
+ 3. Tests pass? (`rake test`)
45
+ 4. Build the gem (`rake build`)
46
+ 5. Release on rubygems.org (`rake release`)
47
+
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  module Zippy
3
- VERSION = '0.1.0'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  end
data/lib/rack-zippy.rb CHANGED
@@ -1,4 +1,4 @@
1
- require "rack-zippy/version"
1
+ require 'rack-zippy/version'
2
2
 
3
3
  module Rack
4
4
  module Zippy
@@ -18,11 +18,8 @@ module Rack
18
18
  file_path = "#{@asset_root}#{path_info}"
19
19
 
20
20
  if ::File.exists?(file_path)
21
- headers = {
22
- 'Content-Type' => Rack::Mime.mime_type(::File.extname(path_info)),
23
- 'Last-Modified' => 'Mon, 10 Jan 2005 10:00:00 GMT',
24
- 'Cache-Control' => "public, max-age=#{max_age_in_secs(path_info)}"
25
- }
21
+ headers = { 'Content-Type' => Rack::Mime.mime_type(::File.extname(path_info)) }
22
+ headers.merge! cache_headers(path_info)
26
23
 
27
24
  gzipped_file_path = "#{file_path}.gz"
28
25
  gzipped_file_present = ::File.exists?(gzipped_file_path)
@@ -66,6 +63,27 @@ module Rack
66
63
 
67
64
  ILLEGAL_PATH_REGEX = /(\.\.|\/\.)/
68
65
 
66
+ # Old last-modified headers encourage caching via browser heuristics. Use it for year-long cached assets.
67
+ CACHE_FRIENDLY_LAST_MODIFIED = 'Mon, 10 Jan 2005 10:00:00 GMT'
68
+
69
+ def cache_headers(path_info)
70
+ case path_info
71
+ when PRECOMPILED_ASSETS_SUBDIR_REGEX
72
+ lifetime = :year
73
+ last_modified = CACHE_FRIENDLY_LAST_MODIFIED
74
+ when '/favicon.ico'
75
+ lifetime = :month
76
+ last_modified = CACHE_FRIENDLY_LAST_MODIFIED
77
+ else
78
+ lifetime = :day
79
+ end
80
+
81
+ headers = { 'Cache-Control' => "public, max-age=#{SECONDS_IN[lifetime]}" }
82
+ headers['Last-Modified'] = last_modified if last_modified
83
+
84
+ return headers
85
+ end
86
+
69
87
  def serve?(path_info)
70
88
  is_compilable_asset = (path_info =~ PRECOMPILED_ASSETS_SUBDIR_REGEX)
71
89
  if is_compilable_asset
@@ -78,19 +96,6 @@ module Rack
78
96
  !::Rails.configuration.assets.compile
79
97
  end
80
98
 
81
- def max_age_in_secs(path_info)
82
- case path_info
83
- when PRECOMPILED_ASSETS_SUBDIR_REGEX
84
- max_age = SECONDS_IN[:year]
85
- when '/favicon.ico'
86
- max_age = SECONDS_IN[:month]
87
- else
88
- max_age = SECONDS_IN[:day]
89
- end
90
-
91
- return max_age
92
- end
93
-
94
99
  def client_accepts_gzip?(rack_env)
95
100
  rack_env['HTTP_ACCEPT_ENCODING'] =~ ACCEPTS_GZIP_REGEX
96
101
  end
@@ -20,6 +20,18 @@ class Rack::Zippy::AssetServerTest < Test::Unit::TestCase
20
20
  Rack::Zippy::AssetServer.new(rack_app)
21
21
  end
22
22
 
23
+ def test_cache_friendly_last_modified_is_not_set_for_files_outside_of_assets_subdir
24
+ get '/robots.txt'
25
+ assert_response_ok
26
+ assert_last_modified nil
27
+ end
28
+
29
+ def test_cache_friendly_last_modified_is_set_for_root_favicon_as_it_rarely_changes
30
+ get '/favicon.ico'
31
+ assert_response_ok
32
+ assert_cache_friendly_last_modified
33
+ end
34
+
23
35
  def test_does_not_serve_assets_subdir_request_when_assets_compile_enabled
24
36
  ::Rails.configuration.assets.compile = true
25
37
  get '/assets/application.css'
@@ -90,21 +102,20 @@ class Rack::Zippy::AssetServerTest < Test::Unit::TestCase
90
102
  get '/favicon.ico'
91
103
  assert_response_ok
92
104
  assert_cache_max_age :month
93
- assert_cache_friendly_last_modified
94
105
  end
95
106
 
96
107
  def test_responds_with_day_long_cache_headers_for_robots_txt
97
108
  get '/robots.txt'
98
109
  assert_response_ok
99
110
  assert_cache_max_age :day
100
- assert_cache_friendly_last_modified
111
+ assert_last_modified nil
101
112
  end
102
113
 
103
114
  def test_responds_with_day_long_cache_headers_for_root_html_requests
104
115
  get '/thanks.html'
105
116
  assert_response_ok
106
117
  assert_cache_max_age :day
107
- assert_cache_friendly_last_modified
118
+ assert_last_modified nil
108
119
  end
109
120
 
110
121
  def test_max_cache_and_vary_accept_encoding_headers_present_for_css_requests_by_non_gzip_clients
@@ -229,6 +240,10 @@ class Rack::Zippy::AssetServerTest < Test::Unit::TestCase
229
240
 
230
241
  DURATIONS_IN_SECS = {:year => 31536000, :month => 2678400, :day => 86400}.freeze
231
242
 
243
+ def assert_last_modified(expected)
244
+ assert_equal expected, last_response.headers['last-modified']
245
+ end
246
+
232
247
  def env_for_gzip_capable_client
233
248
  {'HTTP_ACCEPT_ENCODING' => 'deflate,gzip,sdch'}
234
249
  end
@@ -241,9 +256,9 @@ class Rack::Zippy::AssetServerTest < Test::Unit::TestCase
241
256
  assert_equal "public, max-age=#{DURATIONS_IN_SECS[duration]}", last_response.headers['cache-control']
242
257
  end
243
258
 
244
- # Browsers favour caching assets with older Last Modified dates IIRC
259
+ # Browser caching heuristics favour assets with older Last Modified dates IIRC
245
260
  def assert_cache_friendly_last_modified
246
- assert_equal 'Mon, 10 Jan 2005 10:00:00 GMT', last_response.headers['last-modified']
261
+ assert_last_modified 'Mon, 10 Jan 2005 10:00:00 GMT'
247
262
  end
248
263
 
249
264
  def assert_underlying_app_responded
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-zippy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 1.0.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: 2013-08-21 00:00:00.000000000 Z
12
+ date: 2013-08-22 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: Rack middleware for serving static gzipped assets generated by the Rails
15
15
  asset pipeline