asset_access_control 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,5 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
5
+ *.swp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/CHANGELOG.md ADDED
@@ -0,0 +1,37 @@
1
+ ### master
2
+
3
+ ### 0.1.1 / 2012-01-18
4
+
5
+ [full changelog](https://github.com/rubymaverick/font_assets/compare/v0.1.0...v0.1.1)
6
+
7
+ Bug Fixes
8
+
9
+ * Fix Rack::File#empty? call in middleware causing an exception.
10
+
11
+ ### 0.1.0 / 2012-01-18
12
+
13
+ [full changelog](https://github.com/rubymaverick/font_assets/compare/v0.0.2...v0.1.0)
14
+
15
+ Enhancements
16
+
17
+ * Refactor MIME type settings into a local object.
18
+ * Add RSpec specs on the middleware and mime type handler.
19
+ * Update the README with more detail and examples.
20
+ * Fixed a typo in "ttf" in the middleware.
21
+ * Removed duplicate Railtie definition.
22
+
23
+ Bug Fixes
24
+
25
+ * Fix MIME types not being properly set in recent versions of Rack (starting in [Rack 1.3.0](https://github.com/rack/rack/commit/469518f7d971ba99fc335cf546d605d2364c81aa))
26
+
27
+ ### 0.0.2 / 2011-12-15
28
+
29
+ [full changelog](https://github.com/rubymaverick/font_assets/compare/v0.0.1...v0.0.2)
30
+
31
+ Enhancements
32
+
33
+ * Make MIME setting more future-compatible by optionally setting it.
34
+
35
+ ### 0.0.1 / 2011-12-15
36
+
37
+ Initial release.
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in font_assets.gemspec
4
+ gemspec
data/README.md ADDED
@@ -0,0 +1,111 @@
1
+ Font Assets
2
+ =============
3
+
4
+ This little gem helps serve font-face assets in Rails 3.1. It really does these
5
+ two things:
6
+
7
+ * Responds with "proper" mime types for woff, eot, tff, and svg font files, and
8
+ * Sets Access-Control-Allow-Origin response headers for font assets, which Firefox requires for cross domain fonts.
9
+
10
+ In addition, it will also respond to the pre-flight OPTIONS requests made by
11
+ supporting browsers (Firefox).
12
+
13
+ Install
14
+ -------
15
+
16
+ Add `font_assets` to your Gemfile:
17
+
18
+ ```ruby
19
+ gem 'font_assets'
20
+ ```
21
+
22
+
23
+ Usage
24
+ -----
25
+
26
+ By default, in a Rails application, this gem should Just Work™. However, the
27
+ default settings allow any requesting site to use the linked fonts, due to the
28
+ Allowed Origin being '*', by default. This is only useful for browsers which
29
+ support this feature (Firefox), but restricting it to certain domains may be
30
+ beneficial.
31
+
32
+ Set the origin domain that will get set in the `Access-Control-Allow-Origin`
33
+ header:
34
+
35
+ ```ruby
36
+ # in config/environments/production.rb
37
+ config.font_assets.origin = 'http://codeschool.com'
38
+ ```
39
+
40
+ The origin domain must match the domain of the site serving the page that is
41
+ requesting the font, not the host of the font. For example, if you are using a
42
+ CDN to serve your assets (like CloudFront), and the full path to the font asset
43
+ is `http://d3rd6rvl24noqd.cloudfront.net/assets/fonts/Pacifico-webfont-734f1436e605566ae2f1c132905e28b2.woff`,
44
+ but the URI the user is visiting is `http://coffeescript.codeschool.com/level/1`,
45
+ you'd want to set the origin header to this:
46
+
47
+ ```ruby
48
+ config.font_assets.origin = 'http://coffeescript.codeschool.com'
49
+ ```
50
+
51
+ An Example Response
52
+ -------------------
53
+
54
+ Below is an example response for a .woff font asset on a Rails 3.1 application
55
+ running behind several proxies and caches (including CloudFront):
56
+
57
+ ```
58
+ $ curl -i http://d1tijy5l7mg5kk.cloudfront.net/assets/ubuntu/Ubuntu-Bold-webfont-4bcb5239bfd34be67bc07901959fc6e1.woff
59
+ HTTP/1.0 200 OK
60
+ Server: nginx
61
+ Date: Sat, 14 Jan 2012 19:45:19 GMT
62
+ Content-Type: application/x-font-woff
63
+ Last-Modified: Sat, 14 Jan 2012 16:58:14 GMT
64
+ Cache-Control: public, max-age=31557600
65
+ Access-Control-Allow-Origin: http://www.codeschool.com
66
+ Access-Control-Allow-Methods: GET
67
+ Access-Control-Allow-Headers: x-requested-with
68
+ Access-Control-Max-Age: 3628800
69
+ X-Content-Digest: 66049433125f563329c4178848643536f76459e5
70
+ X-Rack-Cache: fresh
71
+ Content-Length: 17440
72
+ X-Varnish: 311344447
73
+ Age: 289983
74
+ X-Cache: Hit from cloudfront
75
+ X-Amz-Cf-Id: 9yzifs_hIQF_MxPLwSR8zck3eZVXJ8LFKpMUpXnu2SmMuEmyrUbHdQ==,Lbh9kfjr0YRm77seSmOSQ6oFkUEMabvtFStJLhTOy9BfGrIXVneoKQ==
76
+ Via: 1.1 varnish, 1.0 2815dd16e8c2a0074b81a6148bd8aa3a.cloudfront.net:11180 (CloudFront), 1.0 f9e7403ca14431787835521769ace98a.cloudfront.net:11180 (CloudFront)
77
+ Connection: close
78
+ ```
79
+
80
+ In it, you can see where this middleware has injected the `Content-Type` and
81
+ `Access-Control-*` headers into the response.
82
+
83
+ And below is an example OPTIONS request response:
84
+
85
+ ```
86
+ $ curl -i -X OPTIONS http://www.codeschool.com/
87
+ HTTP/1.1 200 OK
88
+ Server: nginx
89
+ Date: Wed, 18 Jan 2012 04:13:25 GMT
90
+ Connection: keep-alive
91
+ Access-Control-Allow-Origin: http://www.codeschool.com
92
+ Access-Control-Allow-Methods: GET
93
+ Access-Control-Allow-Headers: x-requested-with
94
+ Access-Control-Max-Age: 3628800
95
+ Vary: Accept-Encoding
96
+ X-Rack-Cache: invalidate, pass
97
+ Content-Length: 0
98
+ ```
99
+
100
+ License
101
+ -------
102
+
103
+ Font Assets is released under the MIT license.
104
+
105
+ Contributors
106
+ ------------
107
+
108
+ * [Nathanial Bibler](https://github.com/nbibler)
109
+ * [Eric Allam](https://github.com/rubymaverick)
110
+ * [Ryan Montgomery](https://github.com/rmontgomery429)
111
+ * [Jack Foy](https://github.com/jfoy)
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ $:.push File.expand_path("../lib", __FILE__)
4
+ require "asset_access_control/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "asset_access_control"
8
+ s.version = AssetAccessControl::VERSION
9
+ s.authors = ["Eric Allam"]
10
+ s.email = ["rubymaverick@gmail.com"]
11
+ s.homepage = "https://github.com/rubymaverick/asset_access_control"
12
+ s.summary = %q{Set Access Control headers on asset requests in Rails 3.1}
13
+ s.description = %q{Set Access Control headers on asset requests in Rails 3.1}
14
+
15
+ s.rubyforge_project = "asset_access_control"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_dependency "rack"
23
+ s.add_development_dependency "rspec", "~>2.0"
24
+ end
data/bin/autospec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'autospec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'autospec')
data/bin/htmldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'htmldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('diff-lcs', 'htmldiff')
data/bin/ldiff ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'ldiff' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('diff-lcs', 'ldiff')
data/bin/rackup ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rackup' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rack', 'rackup')
data/bin/rspec ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ #
3
+ # This file was generated by Bundler.
4
+ #
5
+ # The application 'rspec' is installed as part of a gem, and
6
+ # this file is here to facilitate running it.
7
+ #
8
+
9
+ require 'pathname'
10
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile",
11
+ Pathname.new(__FILE__).realpath)
12
+
13
+ require 'rubygems'
14
+ require 'bundler/setup'
15
+
16
+ load Gem.bin_path('rspec-core', 'rspec')
@@ -0,0 +1,47 @@
1
+ require 'rack'
2
+
3
+ module AssetAccessControl
4
+ class Middleware
5
+
6
+ def initialize(app, origin)
7
+ @app = app
8
+ @origin = origin
9
+ end
10
+
11
+ def access_control_headers
12
+ {
13
+ "Access-Control-Allow-Origin" => @origin,
14
+ "Access-Control-Allow-Methods" => "GET",
15
+ "Access-Control-Allow-Headers" => "x-requested-with",
16
+ "Access-Control-Max-Age" => "3628800"
17
+ }
18
+ end
19
+
20
+ def call(env)
21
+ # intercept the "preflight" request
22
+ if env["REQUEST_METHOD"] == "OPTIONS"
23
+ return [200, access_control_headers, []]
24
+ else
25
+ code, headers, body = @app.call(env)
26
+ set_headers! headers, body, env["PATH_INFO"]
27
+ [code, headers, body]
28
+ end
29
+ end
30
+
31
+ private
32
+
33
+ def extension(path)
34
+ "." + path.split("?").first.split(".").last
35
+ end
36
+
37
+ def asset?(path)
38
+ %w(.css .js).include? extension(path)
39
+ end
40
+
41
+ def set_headers!(headers, body, path)
42
+ if ext = extension(path) and asset?(ext)
43
+ headers.merge!(access_control_headers)
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,13 @@
1
+ require 'asset_access_control/middleware'
2
+
3
+ module AssetAccessControl
4
+ class Railtie < Rails::Railtie
5
+ config.asset_access_control = ActiveSupport::OrderedOptions.new
6
+
7
+ initializer "asset_access_control.configure_rails_initialization" do |app|
8
+ config.asset_access_control.origin ||= "*"
9
+
10
+ app.middleware.insert_before 'Rack::Lock', AssetAccessControl::Middleware, config.asset_access_control.origin
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,3 @@
1
+ module AssetAccessControl
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,5 @@
1
+ require "asset_access_control/version"
2
+ require "asset_access_control/railtie" if defined?(Rails)
3
+
4
+ module AssetAccessControl
5
+ end
@@ -0,0 +1,88 @@
1
+ require 'spec_helper'
2
+ require 'asset_access_control/middleware'
3
+
4
+ describe AssetAccessControl::Middleware do
5
+ it 'passes all Rack::Lint checks' do
6
+ app = Rack::Lint.new(load_app)
7
+ request app, '/'
8
+ end
9
+
10
+ context 'for GET requests' do
11
+ context 'to a css asset' do
12
+ let(:app) { load_app 'http://test.origin' }
13
+ let(:response) { request app, '/test.css' }
14
+
15
+ context 'the response headers' do
16
+ subject { response[1] }
17
+
18
+ its(["Access-Control-Allow-Headers"]) { should == "x-requested-with" }
19
+ its(["Access-Control-Max-Age"]) { should == "3628800" }
20
+ its(['Access-Control-Allow-Methods']) { should == 'GET' }
21
+ its(['Access-Control-Allow-Origin']) { should == 'http://test.origin' }
22
+ end
23
+ end
24
+
25
+ context 'to a js asset' do
26
+ let(:app) { load_app 'http://test.origin' }
27
+ let(:response) { request app, '/test.js' }
28
+
29
+ context 'the response headers' do
30
+ subject { response[1] }
31
+
32
+ its(["Access-Control-Allow-Headers"]) { should == "x-requested-with" }
33
+ its(["Access-Control-Max-Age"]) { should == "3628800" }
34
+ its(['Access-Control-Allow-Methods']) { should == 'GET' }
35
+ its(['Access-Control-Allow-Origin']) { should == 'http://test.origin' }
36
+ end
37
+ end
38
+
39
+ context 'to a non asset' do
40
+ let(:app) { load_app }
41
+ let(:response) { request app, '/' }
42
+
43
+ context 'the response headers' do
44
+ subject { response[1] }
45
+
46
+ its(["Access-Control-Allow-Headers"]) { should be_nil }
47
+ its(["Access-Control-Max-Age"]) { should be_nil }
48
+ its(['Access-Control-Allow-Methods']) { should be_nil }
49
+ its(['Access-Control-Allow-Origin']) { should be_nil }
50
+ end
51
+ end
52
+ end
53
+
54
+ context 'for OPTIONS requests' do
55
+ let(:app) { load_app 'http://test.options' }
56
+ let(:response) { request app, '/test.css', :method => 'OPTIONS' }
57
+
58
+ context 'the response headers' do
59
+ subject { response[1] }
60
+
61
+ its(["Access-Control-Allow-Headers"]) { should == "x-requested-with" }
62
+ its(["Access-Control-Max-Age"]) { should == "3628800" }
63
+ its(['Access-Control-Allow-Methods']) { should == 'GET' }
64
+ its(['Access-Control-Allow-Origin']) { should == 'http://test.options' }
65
+ end
66
+
67
+ context 'the response body' do
68
+ subject { response[2] }
69
+ it { should be_empty }
70
+ end
71
+ end
72
+
73
+
74
+ private
75
+
76
+
77
+ def load_app(origin = 'http://test.local')
78
+ described_class.new(inner_app, origin)
79
+ end
80
+
81
+ def inner_app
82
+ lambda { |env| [200, {'Content-Type' => 'text/plain'}, 'Success'] }
83
+ end
84
+
85
+ def request(app, path, options = {})
86
+ app.call Rack::MockRequest.env_for(path, options)
87
+ end
88
+ end
@@ -0,0 +1,5 @@
1
+ RSpec.configure do |config|
2
+ config.treat_symbols_as_metadata_keys_with_true_values = true
3
+ config.run_all_when_everything_filtered = true
4
+ config.filter_run :focus
5
+ end
metadata ADDED
@@ -0,0 +1,102 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asset_access_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Allam
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rack
16
+ requirement: !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: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.0'
46
+ description: Set Access Control headers on asset requests in Rails 3.1
47
+ email:
48
+ - rubymaverick@gmail.com
49
+ executables:
50
+ - autospec
51
+ - htmldiff
52
+ - ldiff
53
+ - rackup
54
+ - rspec
55
+ extensions: []
56
+ extra_rdoc_files: []
57
+ files:
58
+ - .gitignore
59
+ - .rspec
60
+ - CHANGELOG.md
61
+ - Gemfile
62
+ - README.md
63
+ - Rakefile
64
+ - asset_access_control.gemspec
65
+ - bin/autospec
66
+ - bin/htmldiff
67
+ - bin/ldiff
68
+ - bin/rackup
69
+ - bin/rspec
70
+ - lib/asset_access_control.rb
71
+ - lib/asset_access_control/middleware.rb
72
+ - lib/asset_access_control/railtie.rb
73
+ - lib/asset_access_control/version.rb
74
+ - spec/middleware_spec.rb
75
+ - spec/spec_helper.rb
76
+ homepage: https://github.com/rubymaverick/asset_access_control
77
+ licenses: []
78
+ post_install_message:
79
+ rdoc_options: []
80
+ require_paths:
81
+ - lib
82
+ required_ruby_version: !ruby/object:Gem::Requirement
83
+ none: false
84
+ requirements:
85
+ - - ! '>='
86
+ - !ruby/object:Gem::Version
87
+ version: '0'
88
+ required_rubygems_version: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ requirements: []
95
+ rubyforge_project: asset_access_control
96
+ rubygems_version: 1.8.24
97
+ signing_key:
98
+ specification_version: 3
99
+ summary: Set Access Control headers on asset requests in Rails 3.1
100
+ test_files:
101
+ - spec/middleware_spec.rb
102
+ - spec/spec_helper.rb