butler_static 0.0.7 → 0.0.8.alpha.20

Sign up to get free protection for your applications and to get access to all the features.
data/README.md CHANGED
@@ -1,6 +1,20 @@
1
1
  # Butler
2
2
 
3
- TODO: Write a gem description
3
+ Butler is a Rack Web Server for Static Files based on ActionDispatch::Static.
4
+ It is intended to be used as a Rails Middleware in an environment where serving static assets through a specialized web server such as nginx is technically not an option.
5
+
6
+ ### Background
7
+
8
+ Butler extends ActionDispatch::Static's functionality to allow a the developer to set custom rules for the HTTP headers that the files sent should carry.
9
+
10
+ The author's intent was to allow Rails to serve static assets with custom HTTP Headers.
11
+ This allows for example serving webfonts or icon fonts carrying the appropriate HTTP headers via a Content Delivery Network (CDN) such as Amazon's Cloudfront. Files requested by the CDN will need to carry the headers the file should be sent with to the visitor's browser already when being sent from the web server.
12
+
13
+ ActionDispatch::Static, Rack::Static et al. don't allow (yet) to add custom HTTP headers to files because the underlying Rack::File implementation only allows for setting a static 'Cache-Control' header.
14
+
15
+ Code and Tests taken from Rails' ActionDispatch::Static.
16
+
17
+ If no matching file can be found in the precompiled assets the request will bubble up to the Rails stack to decide how to handle it, which mimicks ActionDispatch::Static's behaviour.
4
18
 
5
19
  ## Installation
6
20
 
@@ -18,12 +32,94 @@ Or install it yourself as:
18
32
 
19
33
  ## Usage
20
34
 
21
- TODO: Write usage instructions here
35
+ ### Configuration
36
+
37
+ ```ruby
38
+ # config/environment/production.rb
39
+
40
+ # Use Butler
41
+ # to serve precompiled assets
42
+ config.assets.use_butler = true
43
+
44
+ # Rules for HTTP Headers to be set on files
45
+ # sent by Butler
46
+ config.assets.header_rules = {
47
+ rule => {http_field => content},
48
+ rule => {http_field => content}
49
+ }
50
+ ```
51
+
52
+ ### Providing Rules for setting HTTP Headers
53
+
54
+ There are a few way to set rules for all files or files in a certain folder or a certain extension.
55
+
56
+ ```ruby
57
+ # 1) Global Rules
58
+ :global => Matches every file
59
+ Ex.: :global => {
60
+ 'Cache-Control' => 'public, max-age=31536000', # 1 year
61
+ 'Some Custom Header' => 'Some Custom Content'
62
+ }
63
+
64
+ # 2) Folders
65
+ '/folder' => Matches all files in a certain folder
66
+ '/folder/subfolder' => ...
67
+ Note: Provide the folder as a string,
68
+ with or without the starting slash
69
+ Ex.: '/fonts' => {'Access-Control-Allow-Origin' => '*'}
70
+
71
+ # 3) File Extensions
72
+ ['css', 'js'] => Will match all files ending in .css or .js
73
+ %w(css js) => ...
74
+ Note: Provide the file extensions in an array,
75
+ use any ruby syntax you like to set that array up
76
+ Ex.: %w(eot ttf otf woff svg) => {... => ...}
77
+
78
+ # 4) Regular Expressions / Regexp
79
+ %r{\.(?:css|js)\z} => will match all files ending in .css or .js
80
+ /\.(?:eot|ttf|otf|woff|svg)\z/ => will match all files ending
81
+ in the most common web font formats
82
+
83
+ # 5) Shortcuts
84
+ There is currently only one shortcut defined.
85
+ :fonts => will match all files ending in eot, ttf, otf, woff, svg
86
+ using the Regexp stated above
87
+ Ex.: :fonts => {'Access-Control-Allow-Origin' => '*'} # Will allow fonts and icon fonts to be displayed in Firefox 3.5+
88
+
89
+
90
+ Note: The rules will be applied in the order the are listed,
91
+ thus more special rules further down below can override
92
+ general global HTTP header settings
93
+ ```
94
+
95
+ ## Complete Example Use Case
96
+
97
+ The example code below is from a Rails app deployed to [Heroku](http://www.heroku.com) using butler to serve the precompiled assets.
98
+ Cache-Control headers are set on all served files, and Access-Control Headers on Fonts / Icon Fonts.
99
+
100
+ ```ruby
101
+ # config/environment/production.rb
102
+
103
+ # Use Butler
104
+ # to serve precompiled assets
105
+ config.assets.use_butler = true
106
+
107
+ # Rules for HTTP Headers
108
+ # to be set on static files sent by Butler
109
+ config.assets.header_rules = {
110
+ :global => {'Cache-Control' => 'public, max-age=31536000'},
111
+ :fonts => {'Access-Control-Allow-Origin' => '*'}
112
+ }
113
+ ```
114
+ That's it. I hope you like Butler.
115
+ Shoot me an [email](github@tklemm.eu) or [tweet](https://www.twitter.com/thomasjklemm) if you have any questions or thoughts about how to improve Butler. Enjoy your life!
22
116
 
23
117
  ## Contributing
24
118
 
25
119
  1. Fork it
26
120
  2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
121
+ 3. Improve Butler
122
+ 3a. Run tests continually (`bundle exec guard start`) or manually every time (`rake test`)
123
+ 4. Commit your changes (`git commit -am 'Add some feature'`)
124
+ 5. Push to the branch (`git push origin my-new-feature`)
125
+ 6. Create new Pull Request
data/Rakefile CHANGED
@@ -3,6 +3,7 @@ require 'bundler/gem_tasks'
3
3
 
4
4
  # Tests
5
5
  require 'guard'
6
+ desc "Run all tests"
6
7
  task :test do
7
8
  Guard.setup
8
9
  Guard.guards('minitest').run_all
data/butler.gemspec CHANGED
@@ -8,8 +8,8 @@ Gem::Specification.new do |gem|
8
8
  gem.version = Butler::VERSION
9
9
  gem.authors = ["Thomas Klemm"]
10
10
  gem.email = ["github@tklemm.eu"]
11
- gem.description = "Butler is a Rack Middleware that serves static assets for your Rails app."
12
- gem.summary = "Butler is a Rack Middleware that serves static assets for your Rails app. It allows you to set HTTP headers for individual files or folders based on rules."
11
+ gem.description = "Butler is a Rack Middleware that serves static assets for your Rails app. It allows you to set HTTP headers for individual files or folders based on rules."
12
+ gem.summary = "butler_static-#{ Butler::VERSION }"
13
13
  gem.homepage = "https://github.com/thomasklemm/butler"
14
14
 
15
15
  gem.files = `git ls-files`.split($/)
@@ -19,6 +19,7 @@ Gem::Specification.new do |gem|
19
19
 
20
20
  # Dependencies
21
21
  gem.add_dependency 'rack'
22
+ gem.add_dependency 'rails', '>= 3.1.0'
22
23
 
23
24
  # Tests
24
25
  gem.add_development_dependency 'minitest'
@@ -26,6 +27,6 @@ Gem::Specification.new do |gem|
26
27
  gem.add_development_dependency 'turn'
27
28
  # Only ActiveSupport and ActionController nescessary
28
29
  # gem.add_development_dependency 'rails', '~> 3.2.8'
29
- gem.add_development_dependency 'activesupport', '~> 3.2.8'
30
- gem.add_development_dependency 'actionpack', '~> 3.2.8'
30
+ # gem.add_development_dependency 'activesupport', '~> 3.2.8'
31
+ # gem.add_development_dependency 'actionpack', '~> 3.2.8'
31
32
  end
data/lib/butler.rb CHANGED
@@ -2,7 +2,7 @@ require 'butler/version'
2
2
  require 'butler/static'
3
3
  require 'butler/handler'
4
4
  require 'butler/asset'
5
- require 'butler/railtie'
5
+ require 'butler/railtie' if defined? Rails
6
6
 
7
7
  module Butler
8
8
  # Butler
@@ -1,6 +1,30 @@
1
- require 'butler'
2
-
3
1
  module Butler
4
- class Railtie < Rails::Railtie
2
+ class Railtie < ::Rails::Railtie
3
+ puts 'Processing Railtie...'
4
+ # config.butler = ActiveSupport::OrderedOptions.new # enable namespaced configuration in Rails environments
5
+
6
+ # # Config
7
+ # use_butler = Rails.application.config.assets.use_butler || nil
8
+ # path = Rails.application.config.paths['public'].first
9
+
10
+ # header_rules = Rails.application.config.assets.header_rules || {}
11
+ # options = { header_rules: header_rules }
12
+
13
+ initializer "butler.configure_rails_initialization" do |app|
14
+ app.middleware.swap 'ActionDispatch::Static', 'Butler::Static'
15
+ raise app.inspect
16
+ # if use_butler
17
+ # if defined? ActionDispatch::Static
18
+ # if defined? Rack::Cache # will not work
19
+ # app.config.middleware.delete ActionDispatch::Static
20
+ # app.config.middleware.insert_before Rack::Cache, Butler::Static, path, options
21
+ # else
22
+ # app.config.middleware.swap ActionDispatch::Static, Butler::Static, path, options
23
+ # end
24
+ # else
25
+ # app.config.middleware.use Butler::Static, path, options
26
+ # end
27
+ # end
28
+ end
5
29
  end
6
30
  end
data/lib/butler/static.rb CHANGED
@@ -34,7 +34,8 @@ module Butler
34
34
  # the request will bubble up to the Rails stack to decide
35
35
  # how to handle it
36
36
  #
37
- # Usage:
37
+ # Usage with Rails:
38
+ # # config/environment/production.rb
38
39
  # config.middleware.delete ActionDispatch::Static
39
40
  # config.middleware.insert_before Rack::Cache, Butler::Static
40
41
  #
@@ -75,13 +76,12 @@ module Butler
75
76
  # general global HTTP header settings
76
77
  #
77
78
  class Static
78
- def initialize(app, path=nil, options={})
79
- @app = app
80
- path ||= Rails.application.config.paths['public'].first if defined? Rails
81
- header_rules = {}
82
- header_rules = Rails.application.config.assets.header_rules if defined? Rails
83
- header_rules = options[:header_rules] if options[:header_rules]
84
- @file_handler = Butler::Handler.new(path, header_rules: header_rules)
79
+ def initialize(app, path, options={})
80
+ @app = app # Rails app
81
+ config = {}
82
+ # Rules for setting HTTP Headers on files
83
+ config[:header_rules] = options[:header_rules] if options[:header_rules]
84
+ @file_handler = Butler::Handler.new(path, config)
85
85
  end
86
86
 
87
87
  def call(env)
@@ -1,3 +1,3 @@
1
1
  module Butler
2
- VERSION = "0.0.7"
3
- end
2
+ VERSION = "0.0.8.alpha.20"
3
+ end
metadata CHANGED
@@ -1,8 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: butler_static
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.7
5
- prerelease:
4
+ version: 0.0.8.alpha.20
5
+ prerelease: 6
6
6
  platform: ruby
7
7
  authors:
8
8
  - Thomas Klemm
@@ -28,23 +28,23 @@ dependencies:
28
28
  - !ruby/object:Gem::Version
29
29
  version: '0'
30
30
  - !ruby/object:Gem::Dependency
31
- name: minitest
31
+ name: rails
32
32
  requirement: !ruby/object:Gem::Requirement
33
33
  none: false
34
34
  requirements:
35
35
  - - ! '>='
36
36
  - !ruby/object:Gem::Version
37
- version: '0'
38
- type: :development
37
+ version: 3.1.0
38
+ type: :runtime
39
39
  prerelease: false
40
40
  version_requirements: !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ! '>='
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 3.1.0
46
46
  - !ruby/object:Gem::Dependency
47
- name: guard-minitest
47
+ name: minitest
48
48
  requirement: !ruby/object:Gem::Requirement
49
49
  none: false
50
50
  requirements:
@@ -60,7 +60,7 @@ dependencies:
60
60
  - !ruby/object:Gem::Version
61
61
  version: '0'
62
62
  - !ruby/object:Gem::Dependency
63
- name: turn
63
+ name: guard-minitest
64
64
  requirement: !ruby/object:Gem::Requirement
65
65
  none: false
66
66
  requirements:
@@ -76,39 +76,24 @@ dependencies:
76
76
  - !ruby/object:Gem::Version
77
77
  version: '0'
78
78
  - !ruby/object:Gem::Dependency
79
- name: activesupport
80
- requirement: !ruby/object:Gem::Requirement
81
- none: false
82
- requirements:
83
- - - ~>
84
- - !ruby/object:Gem::Version
85
- version: 3.2.8
86
- type: :development
87
- prerelease: false
88
- version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
- requirements:
91
- - - ~>
92
- - !ruby/object:Gem::Version
93
- version: 3.2.8
94
- - !ruby/object:Gem::Dependency
95
- name: actionpack
79
+ name: turn
96
80
  requirement: !ruby/object:Gem::Requirement
97
81
  none: false
98
82
  requirements:
99
- - - ~>
83
+ - - ! '>='
100
84
  - !ruby/object:Gem::Version
101
- version: 3.2.8
85
+ version: '0'
102
86
  type: :development
103
87
  prerelease: false
104
88
  version_requirements: !ruby/object:Gem::Requirement
105
89
  none: false
106
90
  requirements:
107
- - - ~>
91
+ - - ! '>='
108
92
  - !ruby/object:Gem::Version
109
- version: 3.2.8
93
+ version: '0'
110
94
  description: Butler is a Rack Middleware that serves static assets for your Rails
111
- app.
95
+ app. It allows you to set HTTP headers for individual files or folders based on
96
+ rules.
112
97
  email:
113
98
  - github@tklemm.eu
114
99
  executables: []
@@ -175,16 +160,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
175
160
  required_rubygems_version: !ruby/object:Gem::Requirement
176
161
  none: false
177
162
  requirements:
178
- - - ! '>='
163
+ - - ! '>'
179
164
  - !ruby/object:Gem::Version
180
- version: '0'
165
+ version: 1.3.1
181
166
  requirements: []
182
167
  rubyforge_project:
183
168
  rubygems_version: 1.8.23
184
169
  signing_key:
185
170
  specification_version: 3
186
- summary: Butler is a Rack Middleware that serves static assets for your Rails app.
187
- It allows you to set HTTP headers for individual files or folders based on rules.
171
+ summary: butler_static-0.0.8.alpha.20
188
172
  test_files:
189
173
  - spec/butler/asset_spec.rb
190
174
  - spec/butler/files/index.html