asset_host_selection 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,59 @@
1
+ module AssetHostSelection
2
+
3
+ class AssetProvider
4
+
5
+ attr_accessor :enabled, :cdn
6
+
7
+ def self.build_all(attributes = {})
8
+ providers = {}
9
+ attributes.each do |key, settings|
10
+ providers[key.to_sym] = new(settings)
11
+ end
12
+
13
+ providers
14
+ end
15
+
16
+ def initialize(options = {})
17
+ @domain = options.fetch(:domain)
18
+ @subdomain = options.fetch(:subdomain)
19
+ @enabled = options[:enabled]
20
+ @cdn = options[:cdn]
21
+ end
22
+
23
+ def host
24
+ @host ||= [ @subdomain, @domain ].join(".")
25
+ end
26
+
27
+ def enabled?
28
+ return false if @cdn && cdn_disabled?
29
+ @enabled != false
30
+ end
31
+
32
+ protected
33
+
34
+ def cdn_disabled?
35
+ ENV['DISABLE_CDN'] =~ /yes|true/
36
+ end
37
+
38
+ end
39
+
40
+ class AssetHostname
41
+
42
+ def initialize(selector)
43
+ @selector = selector
44
+ end
45
+
46
+ def call(source, request)
47
+ asset_provider = @selector.select(request)
48
+ host = asset_provider.host if asset_provider
49
+
50
+ if host.nil?
51
+ # Relative URL. Useful in dev where no CDNs are configured
52
+ nil
53
+ else
54
+ "http#{"s" if request.ssl?}://#{host}"
55
+ end
56
+ end
57
+
58
+ end
59
+ end
@@ -0,0 +1,109 @@
1
+ require_relative "helper"
2
+
3
+ describe AssetHostSelection do
4
+
5
+ before do
6
+ @providers = AssetHostSelection::AssetProvider.build_all(
7
+ :cdn => { :domain => 'example.com', :subdomain => 'cdn', :enabled => true, :cdn => true },
8
+ :local => { :domain => 'example.com', :subdomain => 'local', :enabled => true, :cdn => false }
9
+ )
10
+ @cdn = @providers[:cdn]
11
+ @local = @providers[:local]
12
+ end
13
+
14
+
15
+ describe "An asset provider" do
16
+
17
+ it "has a host" do
18
+ assert_equal "cdn.example.com", @cdn.host
19
+ assert_equal "local.example.com", @local.host
20
+ end
21
+
22
+ describe "#enabled?" do
23
+ after do
24
+ ENV.delete("DISABLE_CDN")
25
+ end
26
+
27
+ it "is true by default" do
28
+ provider = AssetHostSelection::AssetProvider.new(:domain => "example.com", :subdomain => "hello")
29
+ assert_equal true, provider.enabled?
30
+ end
31
+
32
+ it "is false when disabled" do
33
+ assert @local.enabled?
34
+ @local.enabled = false
35
+
36
+ assert_equal false, @local.enabled?
37
+ end
38
+
39
+ it "is false for CDNs when disabled in the environment" do
40
+ ENV["DISABLE_CDN"] = "true"
41
+ assert_equal false, @cdn.enabled?
42
+ assert_equal true, @local.enabled?
43
+ end
44
+
45
+ it "is true for CDNs when not disabled in the environment" do
46
+ ENV["DISABLE_CDN"] = "somethingelse"
47
+ assert_equal true, @cdn.enabled?
48
+ assert_equal true, @local.enabled?
49
+ end
50
+ end
51
+
52
+ end
53
+
54
+ describe "An asset host" do
55
+ before do
56
+ @asset_host = AssetHostSelection::AssetHostname.new(TestProviderPool.new(@providers))
57
+ end
58
+
59
+ describe "with an SSL request" do
60
+ before do
61
+ @request = cdn_request(:ssl => true, :asset_provider => :cdn)
62
+ end
63
+
64
+ it "uses an encrypted asset host" do
65
+ assert_equal "https://cdn.example.com", @asset_host.call("hello.gif", @request)
66
+ end
67
+ end
68
+
69
+ describe "with a non-SSL request" do
70
+ before do
71
+ @request = cdn_request(:ssl => false, :asset_provider => :cdn)
72
+ end
73
+
74
+ it "uses an unencrypted asset host" do
75
+ assert_equal "http://cdn.example.com", @asset_host.call("hello.gif", @request)
76
+ end
77
+ end
78
+
79
+ end
80
+
81
+ class TestProviderPool
82
+
83
+ attr_reader :providers
84
+
85
+ def initialize(providers)
86
+ @providers = providers
87
+ end
88
+
89
+ def select(request)
90
+ @providers[request.env["asset_provider"]]
91
+ end
92
+
93
+ end
94
+
95
+ def cdn_request(args = {})
96
+ host = args[:host] || "example.com"
97
+ ssl = args[:ssl] || false
98
+ provider = args[:asset_provider]
99
+
100
+ options = { "HTTP_HOST" => host }
101
+ options["HTTPS"] = "on" if ssl
102
+
103
+ env = Rack::MockRequest.env_for("/", options)
104
+ env['asset_provider'] = provider
105
+
106
+ Rack::Request.new(env)
107
+ end
108
+
109
+ end
@@ -0,0 +1,7 @@
1
+ require 'bundler/setup'
2
+ $LOAD_PATH << File.expand_path('../lib', File.dirname(__FILE__))
3
+ require 'asset_host_selection'
4
+ require 'rack/response'
5
+ require 'rack/mock'
6
+ require 'minitest/autorun'
7
+ require 'purdytest'
metadata ADDED
@@ -0,0 +1,100 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asset_host_selection
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Eric Chapweske
9
+ - Morten Primdahl
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2013-07-17 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rake
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ! '>='
21
+ - !ruby/object:Gem::Version
22
+ version: '0'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ! '>='
29
+ - !ruby/object:Gem::Version
30
+ version: '0'
31
+ - !ruby/object:Gem::Dependency
32
+ name: bundler
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
47
+ - !ruby/object:Gem::Dependency
48
+ name: rack
49
+ requirement: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ type: :development
56
+ prerelease: false
57
+ version_requirements: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ description: Adds support for serving assets from multiple providers.
64
+ email:
65
+ - eac@zendesk.com
66
+ executables: []
67
+ extensions: []
68
+ extra_rdoc_files: []
69
+ files:
70
+ - lib/asset_host_selection.rb
71
+ - test/asset_host_selection_test.rb
72
+ - test/helper.rb
73
+ homepage: http://github.com/zendesk/asset_host_selection
74
+ licenses:
75
+ - Apache License Version 2.0
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ required_rubygems_version: !ruby/object:Gem::Requirement
87
+ none: false
88
+ requirements:
89
+ - - ! '>='
90
+ - !ruby/object:Gem::Version
91
+ version: 1.3.6
92
+ requirements: []
93
+ rubyforge_project:
94
+ rubygems_version: 1.8.25
95
+ signing_key:
96
+ specification_version: 3
97
+ summary: Multiple asset host selection for ActionController
98
+ test_files:
99
+ - test/asset_host_selection_test.rb
100
+ - test/helper.rb