action_dispatch-gz_static 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +17 -0
- data/Gemfile +3 -0
- data/README.md +28 -0
- data/Rakefile +8 -0
- data/action_dispatch-gz_static.gemspec +18 -0
- data/lib/action_dispatch/gz_railtie.rb +9 -0
- data/lib/action_dispatch/gz_static.rb +81 -0
- data/test/gz_static_test.rb +179 -0
- data/test/public/.gitignore +1 -0
- data/test/public/404.html +1 -0
- data/test/public/500.da.html +1 -0
- data/test/public/500.html +1 -0
- data/test/public/compressed.html +1 -0
- data/test/public/compressed.html.gz +0 -0
- data/test/public/elsewhere/cools.js +1 -0
- data/test/public/elsewhere/file.css +1 -0
- data/test/public/foo/bar.html +1 -0
- data/test/public/foo/baz.css +3 -0
- data/test/public/foo/index.html +1 -0
- data/test/public/foo//343/201/223/343/202/223/343/201/253/343/201/241/343/201/257.html +1 -0
- data/test/public/images/rails.png +0 -0
- data/test/public/index.html +1 -0
- data/test/public/javascripts/application.js +1 -0
- data/test/public/javascripts/bank.js +1 -0
- data/test/public/javascripts/common.javascript +1 -0
- data/test/public/javascripts/controls.js +1 -0
- data/test/public/javascripts/dragdrop.js +1 -0
- data/test/public/javascripts/effects.js +1 -0
- data/test/public/javascripts/prototype.js +1 -0
- data/test/public/javascripts/robber.js +1 -0
- data/test/public/javascripts/subdir/subdir.js +1 -0
- data/test/public/javascripts/version.1.0.js +1 -0
- data/test/public/stylesheets/bank.css +1 -0
- data/test/public/stylesheets/random.styles +1 -0
- data/test/public/stylesheets/robber.css +1 -0
- data/test/public/stylesheets/subdir/subdir.css +1 -0
- data/test/public/stylesheets/version.1.0.css +1 -0
- metadata +142 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,28 @@
|
|
1
|
+
# ActionDispatch::GzStatic
|
2
|
+
|
3
|
+
ActionDispatch::GzStatic is a derivative of ActionDispatch::Static, that has
|
4
|
+
been modified to serve the .gz files that are created by the Rails asset
|
5
|
+
precompiler.
|
6
|
+
|
7
|
+
If you are using Rails to serve static assets in production, and
|
8
|
+
you are using the asset precompiler, then it is probably a good idea to use this
|
9
|
+
gem. If you running on Heroku's Cedar stack, this includes you.
|
10
|
+
|
11
|
+
ActionDispatch::GzStatic is a better solution that using Rack::Deflater on your
|
12
|
+
static assets, because this has the undesirable side effect of recompressing
|
13
|
+
assets that are already compressed, such as images.
|
14
|
+
|
15
|
+
## Installation
|
16
|
+
|
17
|
+
Add this line to your application's Gemfile:
|
18
|
+
|
19
|
+
gem 'action_dispatch-gz_static'
|
20
|
+
|
21
|
+
Add this to application.rb:
|
22
|
+
|
23
|
+
# The railtie initializer will look for ActionDispatch::Static, and swap it
|
24
|
+
# with ActionDispatch::GzStatic
|
25
|
+
config.serve_static_assets = true
|
26
|
+
|
27
|
+
# This isn't required, but is generally a good idea.
|
28
|
+
config.static_cache_control = "public, max-age=#{1.month.to_i}"
|
data/Rakefile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
Gem::Specification.new do |gem|
|
3
|
+
gem.name = "action_dispatch-gz_static"
|
4
|
+
gem.version = '0.0.1'
|
5
|
+
gem.authors = ["Jonathan Baudanza"]
|
6
|
+
gem.email = ["jon@jonb.org"]
|
7
|
+
gem.description = %q{Serves the .gz files that are created by the asset precompiler}
|
8
|
+
gem.summary = %q{Serves the .gz files that are created by the asset precompiler}
|
9
|
+
gem.homepage = "https://github.com/jbaudanza/action_dispatch-gz_static"
|
10
|
+
|
11
|
+
gem.add_dependency('actionpack', '>= 3.1.0', '< 4')
|
12
|
+
gem.add_dependency('railties', '>= 3.1.0', '< 4')
|
13
|
+
|
14
|
+
gem.files = `git ls-files`.split($/).collect{ |str| str[0] == '"' ? eval(str) : str }
|
15
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
16
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
17
|
+
gem.require_paths = ["lib"]
|
18
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
module ActionDispatch
|
2
|
+
class GzRailtie < Rails::Railtie
|
3
|
+
initializer "gz_static.install_middleware" do |app|
|
4
|
+
app.middleware.swap ::ActionDispatch::Static, ::ActionDispatch::GzStatic,
|
5
|
+
app.paths['public'].first,
|
6
|
+
app.config.static_cache_control
|
7
|
+
end
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rack/utils'
|
3
|
+
require 'rack/mime'
|
4
|
+
require 'rack/file'
|
5
|
+
require 'active_support/core_ext/uri'
|
6
|
+
|
7
|
+
require 'action_dispatch/gz_railtie' if defined?(Rails)
|
8
|
+
|
9
|
+
module ActionDispatch
|
10
|
+
class GzStatic
|
11
|
+
def initialize(app, root, cache_control=nil)
|
12
|
+
@app = app
|
13
|
+
@root = root.chomp('/')
|
14
|
+
@compiled_root = /^#{Regexp.escape(@root)}/
|
15
|
+
@file_server = ::Rack::File.new(@root, cache_control)
|
16
|
+
end
|
17
|
+
|
18
|
+
def match?(path)
|
19
|
+
path = path.dup
|
20
|
+
|
21
|
+
full_path = path.empty? ? @root : File.join(@root, escape_glob_chars(unescape_path(path)))
|
22
|
+
paths = "#{full_path}#{ext}"
|
23
|
+
|
24
|
+
matches = Dir[paths]
|
25
|
+
matches.detect { |m| File.file?(m) }
|
26
|
+
end
|
27
|
+
|
28
|
+
def call(env)
|
29
|
+
case env['REQUEST_METHOD']
|
30
|
+
when 'GET', 'HEAD'
|
31
|
+
path = env['PATH_INFO'].chomp('/')
|
32
|
+
if match = match?(path)
|
33
|
+
|
34
|
+
compressed_match = "#{match}.gz"
|
35
|
+
compressed_exists = File.file?(compressed_match)
|
36
|
+
|
37
|
+
wants_compressed = !!(env['HTTP_ACCEPT_ENCODING'] =~ /\bgzip\b/)
|
38
|
+
|
39
|
+
if wants_compressed && compressed_exists
|
40
|
+
mime = Rack::Mime.mime_type(::File.extname(match), 'text/plain')
|
41
|
+
match = compressed_match
|
42
|
+
end
|
43
|
+
|
44
|
+
match.sub!(@compiled_root, '')
|
45
|
+
env["PATH_INFO"] = ::Rack::Utils.escape(match)
|
46
|
+
status, headers, body = @file_server.call(env)
|
47
|
+
|
48
|
+
if compressed_exists
|
49
|
+
headers['Vary'] = 'Accept-Encoding'
|
50
|
+
|
51
|
+
if wants_compressed
|
52
|
+
headers['Content-Encoding'] = 'gzip'
|
53
|
+
headers['Content-Type'] = mime if mime
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
return [status, headers, body]
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
@app.call(env)
|
62
|
+
end
|
63
|
+
|
64
|
+
def ext
|
65
|
+
@ext ||= begin
|
66
|
+
#ext = ::ActionController::Base.default_static_extension
|
67
|
+
ext = ".html"
|
68
|
+
"{,#{ext},/index#{ext}}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
def unescape_path(path)
|
73
|
+
URI.parser.unescape(path)
|
74
|
+
end
|
75
|
+
|
76
|
+
def escape_glob_chars(path)
|
77
|
+
path.force_encoding('binary') if path.respond_to? :force_encoding
|
78
|
+
path.gsub(/[*?{}\[\]]/, "\\\\\\&")
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'minitest/autorun'
|
3
|
+
require 'rbconfig'
|
4
|
+
require 'active_support'
|
5
|
+
require 'action_dispatch/gz_static'
|
6
|
+
require 'rack/mock'
|
7
|
+
require 'zlib'
|
8
|
+
|
9
|
+
PUBLIC_LOAD_PATH = File.join(File.dirname(__FILE__), 'public')
|
10
|
+
|
11
|
+
module StaticTests
|
12
|
+
def test_serves_dynamic_content
|
13
|
+
assert_equal "Hello, World!", get("/nofile").body
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_handles_urls_with_bad_encoding
|
17
|
+
assert_equal "Hello, World!", get("/doorkeeper%E3E4").body
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_sets_cache_control
|
21
|
+
response = get("/index.html")
|
22
|
+
assert_html "/index.html", response
|
23
|
+
assert_equal "public, max-age=60", response.headers["Cache-Control"]
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_serves_static_index_at_root
|
27
|
+
assert_html "/index.html", get("/index.html")
|
28
|
+
assert_html "/index.html", get("/index")
|
29
|
+
assert_html "/index.html", get("/")
|
30
|
+
assert_html "/index.html", get("")
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_serves_static_file_in_directory
|
34
|
+
assert_html "/foo/bar.html", get("/foo/bar.html")
|
35
|
+
assert_html "/foo/bar.html", get("/foo/bar/")
|
36
|
+
assert_html "/foo/bar.html", get("/foo/bar")
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_serves_static_index_file_in_directory
|
40
|
+
assert_html "/foo/index.html", get("/foo/index.html")
|
41
|
+
assert_html "/foo/index.html", get("/foo/")
|
42
|
+
assert_html "/foo/index.html", get("/foo")
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_served_static_file_with_non_english_filename
|
46
|
+
assert_html "means hello in Japanese\n", get("/foo/#{Rack::Utils.escape("こんにちは.html")}")
|
47
|
+
end
|
48
|
+
|
49
|
+
|
50
|
+
def test_serves_static_file_with_exclamation_mark_in_filename
|
51
|
+
with_static_file "/foo/foo!bar.html" do |file|
|
52
|
+
assert_html file, get("/foo/foo%21bar.html")
|
53
|
+
assert_html file, get("/foo/foo!bar.html")
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def test_serves_static_file_with_dollar_sign_in_filename
|
58
|
+
with_static_file "/foo/foo$bar.html" do |file|
|
59
|
+
assert_html file, get("/foo/foo%24bar.html")
|
60
|
+
assert_html file, get("/foo/foo$bar.html")
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def test_serves_static_file_with_ampersand_in_filename
|
65
|
+
with_static_file "/foo/foo&bar.html" do |file|
|
66
|
+
assert_html file, get("/foo/foo%26bar.html")
|
67
|
+
assert_html file, get("/foo/foo&bar.html")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def test_serves_static_file_with_apostrophe_in_filename
|
72
|
+
with_static_file "/foo/foo'bar.html" do |file|
|
73
|
+
assert_html file, get("/foo/foo%27bar.html")
|
74
|
+
assert_html file, get("/foo/foo'bar.html")
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_serves_static_file_with_parentheses_in_filename
|
79
|
+
with_static_file "/foo/foo(bar).html" do |file|
|
80
|
+
assert_html file, get("/foo/foo%28bar%29.html")
|
81
|
+
assert_html file, get("/foo/foo(bar).html")
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_serves_static_file_with_plus_sign_in_filename
|
86
|
+
with_static_file "/foo/foo+bar.html" do |file|
|
87
|
+
assert_html file, get("/foo/foo%2Bbar.html")
|
88
|
+
assert_html file, get("/foo/foo+bar.html")
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
def test_serves_static_file_with_comma_in_filename
|
93
|
+
with_static_file "/foo/foo,bar.html" do |file|
|
94
|
+
assert_html file, get("/foo/foo%2Cbar.html")
|
95
|
+
assert_html file, get("/foo/foo,bar.html")
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
def test_serves_static_file_with_semi_colon_in_filename
|
100
|
+
with_static_file "/foo/foo;bar.html" do |file|
|
101
|
+
assert_html file, get("/foo/foo%3Bbar.html")
|
102
|
+
assert_html file, get("/foo/foo;bar.html")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
def test_serves_static_file_with_at_symbol_in_filename
|
107
|
+
with_static_file "/foo/foo@bar.html" do |file|
|
108
|
+
assert_html file, get("/foo/foo%40bar.html")
|
109
|
+
assert_html file, get("/foo/foo@bar.html")
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_serves_uncompressed_file
|
114
|
+
response = get('/compressed.html')
|
115
|
+
assert_equal 200, response.status
|
116
|
+
assert_html "Hello, static file", response
|
117
|
+
assert_equal "Accept-Encoding", response.headers['Vary']
|
118
|
+
assert_nil response.headers['Content-Encoding']
|
119
|
+
end
|
120
|
+
|
121
|
+
def test_serves_compressed_file
|
122
|
+
response = get('/compressed.html', 'HTTP_ACCEPT_ENCODING' => 'gzip')
|
123
|
+
assert_equal 200, response.status
|
124
|
+
gz = Zlib::GzipReader.new(StringIO.new(response.body))
|
125
|
+
assert_equal "Hello, static file", gz.read
|
126
|
+
assert_equal "Accept-Encoding", response.headers['Vary']
|
127
|
+
assert_equal "gzip", response.headers['Content-Encoding']
|
128
|
+
assert_equal "text/html", response.headers['Content-Type']
|
129
|
+
end
|
130
|
+
|
131
|
+
# Windows doesn't allow \ / : * ? " < > | in filenames
|
132
|
+
unless RbConfig::CONFIG['host_os'] =~ /mswin|mingw/
|
133
|
+
def test_serves_static_file_with_colon
|
134
|
+
with_static_file "/foo/foo:bar.html" do |file|
|
135
|
+
assert_html file, get("/foo/foo%3Abar.html")
|
136
|
+
assert_html file, get("/foo/foo:bar.html")
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
def test_serves_static_file_with_asterisk
|
141
|
+
with_static_file "/foo/foo*bar.html" do |file|
|
142
|
+
assert_html file, get("/foo/foo%2Abar.html")
|
143
|
+
assert_html file, get("/foo/foo*bar.html")
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def assert_html(body, response)
|
151
|
+
assert_equal body, response.body
|
152
|
+
assert_equal "text/html", response.headers["Content-Type"]
|
153
|
+
end
|
154
|
+
|
155
|
+
def get(path, opts={})
|
156
|
+
Rack::MockRequest.new(@app).request("GET", path, opts)
|
157
|
+
end
|
158
|
+
|
159
|
+
def with_static_file(file)
|
160
|
+
path = PUBLIC_LOAD_PATH + file
|
161
|
+
File.open(path, "wb+") { |f| f.write(file) }
|
162
|
+
yield file
|
163
|
+
ensure
|
164
|
+
File.delete(path)
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
class StaticTest < ActiveSupport::TestCase
|
169
|
+
DummyApp = lambda { |env|
|
170
|
+
[200, {"Content-Type" => "text/plain"}, ["Hello, World!"]]
|
171
|
+
}
|
172
|
+
App = ActionDispatch::GzStatic.new(DummyApp, PUBLIC_LOAD_PATH, "public, max-age=60")
|
173
|
+
|
174
|
+
def setup
|
175
|
+
@app = App
|
176
|
+
end
|
177
|
+
|
178
|
+
include StaticTests
|
179
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
absolute/*
|
@@ -0,0 +1 @@
|
|
1
|
+
404 error fixture
|
@@ -0,0 +1 @@
|
|
1
|
+
500 localized error fixture
|
@@ -0,0 +1 @@
|
|
1
|
+
500 error fixture
|
@@ -0,0 +1 @@
|
|
1
|
+
Hello, static file
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
// cools.js
|
@@ -0,0 +1 @@
|
|
1
|
+
/*file.css*/
|
@@ -0,0 +1 @@
|
|
1
|
+
/foo/bar.html
|
@@ -0,0 +1 @@
|
|
1
|
+
/foo/index.html
|
@@ -0,0 +1 @@
|
|
1
|
+
means hello in Japanese
|
Binary file
|
@@ -0,0 +1 @@
|
|
1
|
+
/index.html
|
@@ -0,0 +1 @@
|
|
1
|
+
// application js
|
@@ -0,0 +1 @@
|
|
1
|
+
// bank js
|
@@ -0,0 +1 @@
|
|
1
|
+
// common.javascript
|
@@ -0,0 +1 @@
|
|
1
|
+
// controls js
|
@@ -0,0 +1 @@
|
|
1
|
+
// dragdrop js
|
@@ -0,0 +1 @@
|
|
1
|
+
// effects js
|
@@ -0,0 +1 @@
|
|
1
|
+
// prototype js
|
@@ -0,0 +1 @@
|
|
1
|
+
// robber js
|
@@ -0,0 +1 @@
|
|
1
|
+
// subdir js
|
@@ -0,0 +1 @@
|
|
1
|
+
// version.1.0 js
|
@@ -0,0 +1 @@
|
|
1
|
+
/* bank.css */
|
@@ -0,0 +1 @@
|
|
1
|
+
/* random.styles */
|
@@ -0,0 +1 @@
|
|
1
|
+
/* robber.css */
|
@@ -0,0 +1 @@
|
|
1
|
+
/* subdir.css */
|
@@ -0,0 +1 @@
|
|
1
|
+
/* version.1.0.css */
|
metadata
ADDED
@@ -0,0 +1,142 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: action_dispatch-gz_static
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jonathan Baudanza
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-02-27 00:00:00.000000000 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: actionpack
|
17
|
+
requirement: &2160710380 !ruby/object:Gem::Requirement
|
18
|
+
none: false
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 3.1.0
|
23
|
+
- - <
|
24
|
+
- !ruby/object:Gem::Version
|
25
|
+
version: '4'
|
26
|
+
type: :runtime
|
27
|
+
prerelease: false
|
28
|
+
version_requirements: *2160710380
|
29
|
+
- !ruby/object:Gem::Dependency
|
30
|
+
name: railties
|
31
|
+
requirement: &2160708340 !ruby/object:Gem::Requirement
|
32
|
+
none: false
|
33
|
+
requirements:
|
34
|
+
- - ! '>='
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 3.1.0
|
37
|
+
- - <
|
38
|
+
- !ruby/object:Gem::Version
|
39
|
+
version: '4'
|
40
|
+
type: :runtime
|
41
|
+
prerelease: false
|
42
|
+
version_requirements: *2160708340
|
43
|
+
description: Serves the .gz files that are created by the asset precompiler
|
44
|
+
email:
|
45
|
+
- jon@jonb.org
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gitignore
|
51
|
+
- Gemfile
|
52
|
+
- README.md
|
53
|
+
- Rakefile
|
54
|
+
- action_dispatch-gz_static.gemspec
|
55
|
+
- lib/action_dispatch/gz_railtie.rb
|
56
|
+
- lib/action_dispatch/gz_static.rb
|
57
|
+
- test/gz_static_test.rb
|
58
|
+
- test/public/.gitignore
|
59
|
+
- test/public/404.html
|
60
|
+
- test/public/500.da.html
|
61
|
+
- test/public/500.html
|
62
|
+
- test/public/compressed.html
|
63
|
+
- test/public/compressed.html.gz
|
64
|
+
- test/public/elsewhere/cools.js
|
65
|
+
- test/public/elsewhere/file.css
|
66
|
+
- test/public/foo/bar.html
|
67
|
+
- test/public/foo/baz.css
|
68
|
+
- test/public/foo/index.html
|
69
|
+
- test/public/foo/こんにちは.html
|
70
|
+
- test/public/images/rails.png
|
71
|
+
- test/public/index.html
|
72
|
+
- test/public/javascripts/application.js
|
73
|
+
- test/public/javascripts/bank.js
|
74
|
+
- test/public/javascripts/common.javascript
|
75
|
+
- test/public/javascripts/controls.js
|
76
|
+
- test/public/javascripts/dragdrop.js
|
77
|
+
- test/public/javascripts/effects.js
|
78
|
+
- test/public/javascripts/prototype.js
|
79
|
+
- test/public/javascripts/robber.js
|
80
|
+
- test/public/javascripts/subdir/subdir.js
|
81
|
+
- test/public/javascripts/version.1.0.js
|
82
|
+
- test/public/stylesheets/bank.css
|
83
|
+
- test/public/stylesheets/random.styles
|
84
|
+
- test/public/stylesheets/robber.css
|
85
|
+
- test/public/stylesheets/subdir/subdir.css
|
86
|
+
- test/public/stylesheets/version.1.0.css
|
87
|
+
has_rdoc: true
|
88
|
+
homepage: https://github.com/jbaudanza/action_dispatch-gz_static
|
89
|
+
licenses: []
|
90
|
+
post_install_message:
|
91
|
+
rdoc_options: []
|
92
|
+
require_paths:
|
93
|
+
- lib
|
94
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
95
|
+
none: false
|
96
|
+
requirements:
|
97
|
+
- - ! '>='
|
98
|
+
- !ruby/object:Gem::Version
|
99
|
+
version: '0'
|
100
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
101
|
+
none: false
|
102
|
+
requirements:
|
103
|
+
- - ! '>='
|
104
|
+
- !ruby/object:Gem::Version
|
105
|
+
version: '0'
|
106
|
+
requirements: []
|
107
|
+
rubyforge_project:
|
108
|
+
rubygems_version: 1.6.2
|
109
|
+
signing_key:
|
110
|
+
specification_version: 3
|
111
|
+
summary: Serves the .gz files that are created by the asset precompiler
|
112
|
+
test_files:
|
113
|
+
- test/gz_static_test.rb
|
114
|
+
- test/public/.gitignore
|
115
|
+
- test/public/404.html
|
116
|
+
- test/public/500.da.html
|
117
|
+
- test/public/500.html
|
118
|
+
- test/public/compressed.html
|
119
|
+
- test/public/compressed.html.gz
|
120
|
+
- test/public/elsewhere/cools.js
|
121
|
+
- test/public/elsewhere/file.css
|
122
|
+
- test/public/foo/bar.html
|
123
|
+
- test/public/foo/baz.css
|
124
|
+
- test/public/foo/index.html
|
125
|
+
- test/public/foo/こんにちは.html
|
126
|
+
- test/public/images/rails.png
|
127
|
+
- test/public/index.html
|
128
|
+
- test/public/javascripts/application.js
|
129
|
+
- test/public/javascripts/bank.js
|
130
|
+
- test/public/javascripts/common.javascript
|
131
|
+
- test/public/javascripts/controls.js
|
132
|
+
- test/public/javascripts/dragdrop.js
|
133
|
+
- test/public/javascripts/effects.js
|
134
|
+
- test/public/javascripts/prototype.js
|
135
|
+
- test/public/javascripts/robber.js
|
136
|
+
- test/public/javascripts/subdir/subdir.js
|
137
|
+
- test/public/javascripts/version.1.0.js
|
138
|
+
- test/public/stylesheets/bank.css
|
139
|
+
- test/public/stylesheets/random.styles
|
140
|
+
- test/public/stylesheets/robber.css
|
141
|
+
- test/public/stylesheets/subdir/subdir.css
|
142
|
+
- test/public/stylesheets/version.1.0.css
|