asset_host_selection 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.
@@ -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