rack-zippy 0.1.0 → 1.0.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.
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