excursion 0.1.9 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/app/assets/javascripts/excursion.js +14 -4
- data/lib/excursion.rb +0 -1
- data/lib/excursion/builders/application_builder.rb +0 -3
- data/lib/excursion/builders/url_builder.rb +15 -9
- data/lib/excursion/cors.rb +15 -5
- data/lib/excursion/datastores/test.rb +15 -3
- data/lib/excursion/pool.rb +37 -17
- data/lib/excursion/pool/application.rb +1 -1
- data/lib/excursion/railtie.rb +3 -5
- data/lib/excursion/version.rb +1 -1
- data/spec/controllers/excursion_controller_spec.rb +4 -0
- data/spec/dummy/config/application.rb +1 -45
- data/spec/dummy/config/environments/development.rb +0 -6
- data/spec/dummy/config/environments/production.rb +1 -51
- data/spec/dummy/config/environments/test.rb +0 -7
- data/spec/dummy/config/initializers/wrap_parameters.rb +9 -7
- data/spec/dummy/config/routes.rb +1 -0
- data/spec/dummy/log/development.log +29110 -0
- data/spec/excursion/cors_spec.rb +4 -0
- data/spec/excursion/pool_spec.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- metadata +22 -5
- data/lib/excursion/asset_middleware.rb +0 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 247f6d9899025734c8fa19d644009f701d9afb14
|
4
|
+
data.tar.gz: ddce03accc06bb78099ecd0f5935e11a0dc03006
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a70fcbc556abaf862e7779639eef2d682ec1dddef96b5db19bfca367baff57ff9c6bfb83e8de6ed8810c8f6506ef189bde0931fcb4e098944b515e572298bede
|
7
|
+
data.tar.gz: 0dce8684d71b0b456a1375be1d82e60e4bc0361f0c57f5c21aed17d1a2873265bcfce0259f880779e2ab59bc784c9a3477a2cc321112d51653df813b623a31c9
|
@@ -169,11 +169,21 @@ Base64 = (function() {
|
|
169
169
|
return replaced;
|
170
170
|
};
|
171
171
|
thisApp[routeName + '_url'] = function() {
|
172
|
-
var
|
173
|
-
|
174
|
-
|
172
|
+
var args = Array.prototype.slice.call(arguments);
|
173
|
+
|
174
|
+
if (args.length > 0 && args[args.length - 1].host) {
|
175
|
+
var urlArgs = args.pop();
|
176
|
+
if (!urlArgs.port)
|
177
|
+
urlArgs.port = thisApp.default_url_options.port;
|
178
|
+
} else {
|
179
|
+
var urlArgs = thisApp.default_url_options;
|
180
|
+
}
|
181
|
+
|
182
|
+
var urlOpts = window.location.protocol + '//' + urlArgs.host;
|
183
|
+
if (urlArgs.port && parseInt(urlArgs.port) != 80)
|
184
|
+
urlOpts += ':' + urlArgs.port;
|
175
185
|
|
176
|
-
return urlOpts + thisApp[routeName + '_path'](
|
186
|
+
return urlOpts + thisApp[routeName + '_path'](args);
|
177
187
|
};
|
178
188
|
}(this));
|
179
189
|
}
|
data/lib/excursion.rb
CHANGED
@@ -10,19 +10,20 @@ module Excursion
|
|
10
10
|
application.routes
|
11
11
|
end
|
12
12
|
|
13
|
+
def url_for(route, *args)
|
14
|
+
ActionDispatch::Http::URL.url_for(route_options(route, *args))
|
15
|
+
end
|
16
|
+
|
13
17
|
def method_missing(meth, *args)
|
14
18
|
route = application.route(route_name_from_method(meth))
|
15
|
-
if route
|
16
|
-
super
|
17
|
-
else
|
19
|
+
if route
|
18
20
|
if meth.to_s.match(/_url\Z/)
|
19
|
-
|
20
|
-
url_opts.merge!(args.slice!(args.length-1)) if args.last.is_a?(Hash) #&& args.last.has_key?(:host)
|
21
|
-
|
22
|
-
ActionDispatch::Http::URL.url_for(url_opts.merge({path: replaced_path(route, args)}))
|
21
|
+
url_for(route, *args)
|
23
22
|
elsif meth.to_s.match(/_path\Z/)
|
24
|
-
replaced_path(route, args)
|
23
|
+
replaced_path(route, *args)
|
25
24
|
end
|
25
|
+
else
|
26
|
+
super
|
26
27
|
end
|
27
28
|
end
|
28
29
|
|
@@ -36,6 +37,11 @@ module Excursion
|
|
36
37
|
@appname = app_name
|
37
38
|
end
|
38
39
|
|
40
|
+
def route_options(route, *args)
|
41
|
+
opts = args.extract_options!
|
42
|
+
application.default_url_options.merge(opts).merge({path: replaced_path(route, *args)})
|
43
|
+
end
|
44
|
+
|
39
45
|
def route_name_from_method(meth)
|
40
46
|
meth.to_s.gsub(/_(url|path)\Z/,'').to_sym
|
41
47
|
end
|
@@ -43,7 +49,7 @@ module Excursion
|
|
43
49
|
# Very hacky method to replace path parts with values
|
44
50
|
#
|
45
51
|
# Needs work, particularly around formatting which is basically ignored right now.
|
46
|
-
def replaced_path(route, args)
|
52
|
+
def replaced_path(route, *args)
|
47
53
|
path = route.path.spec.to_s.dup
|
48
54
|
|
49
55
|
route.required_parts.zip(args) do |part, arg|
|
data/lib/excursion/cors.rb
CHANGED
@@ -9,18 +9,28 @@ module Excursion
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def cors_whitelisted?(origin)
|
12
|
-
|
13
|
-
|
12
|
+
if Excursion.configuration.cors_whitelist == :pool
|
13
|
+
Excursion::Pool.all_applications.values.map { |app| app.default_url_options[:host] }.any? { |cw| cors_match? origin, cw }
|
14
|
+
else
|
15
|
+
Excursion.configuration.cors_whitelist.nil? || Excursion.configuration.cors_whitelist.any? { |cw| cors_match? origin, cw }
|
16
|
+
end
|
14
17
|
end
|
15
18
|
|
16
19
|
def cors_blacklisted?(origin)
|
17
20
|
!Excursion.configuration.cors_blacklist.nil? && !Excursion.configuration.cors_blacklist.any? { |cb| cors_match? origin, cb }
|
18
21
|
end
|
19
22
|
|
23
|
+
def origin_header
|
24
|
+
request.headers['Origin'] || request.headers['HTTP_ORIGIN']
|
25
|
+
end
|
26
|
+
|
27
|
+
def origin_allowed?
|
28
|
+
!origin_header.nil? && cors_whitelisted?(origin_header) && !cors_blacklisted?(origin_header)
|
29
|
+
end
|
30
|
+
|
20
31
|
def cors_headers
|
21
|
-
|
22
|
-
|
23
|
-
headers['Access-Control-Allow-Origin'] = request.headers['Origin']
|
32
|
+
if origin_allowed?
|
33
|
+
headers['Access-Control-Allow-Origin'] = origin_header
|
24
34
|
headers['Access-Control-Allow-Methods'] = Excursion.configuration.cors_allow_methods.join(',')
|
25
35
|
headers['Access-Control-Allow-Headers'] = Excursion.configuration.cors_allow_headers.join(', ')
|
26
36
|
headers['Access-Control-Allow-Credentials'] = Excursion.configuration.cors_allow_credentials.to_s
|
@@ -12,10 +12,10 @@ module Excursion
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def read(key)
|
15
|
-
return @pool[key.to_sym] if
|
15
|
+
return @pool[key.to_sym] if option_key?(key)
|
16
16
|
|
17
|
-
return unless
|
18
|
-
@pool[key.to_sym] ||= application_class.new(key,
|
17
|
+
return unless test_provider?(key)
|
18
|
+
@pool[key.to_sym] ||= application_class.new(key, default_options, ActionDispatch::Routing::RouteSet::NamedRouteCollection.new).to_cache
|
19
19
|
end
|
20
20
|
alias_method :get, :read
|
21
21
|
|
@@ -39,6 +39,18 @@ module Excursion
|
|
39
39
|
@pool = {}
|
40
40
|
@pool = pool.dup unless pool.nil?
|
41
41
|
end
|
42
|
+
|
43
|
+
def test_provider?(key)
|
44
|
+
Excursion.configuration.test_providers.nil? || Excursion.configuration.test_providers.map(&:to_sym).include?(key.to_sym)
|
45
|
+
end
|
46
|
+
|
47
|
+
def default_options
|
48
|
+
{default_url_options: {host: 'www.example.com'}}
|
49
|
+
end
|
50
|
+
|
51
|
+
def option_key?(key)
|
52
|
+
key.to_s.match(/^_.*/) && @pool.has_key?(key.to_sym)
|
53
|
+
end
|
42
54
|
end
|
43
55
|
end
|
44
56
|
end
|
data/lib/excursion/pool.rb
CHANGED
@@ -22,6 +22,10 @@ module Excursion
|
|
22
22
|
@@applications[name.to_s] = app unless app.nil?
|
23
23
|
end
|
24
24
|
|
25
|
+
def self.app_hash_defaults
|
26
|
+
{default_url_options: Excursion.configuration.default_url_options, routes: {}, registered_at: Time.now}
|
27
|
+
end
|
28
|
+
|
25
29
|
def self.register_application(app=nil, opts={}, &block)
|
26
30
|
raise ArgumentError, "app must be an instance of Rails::Application" unless app.is_a?(Rails::Application) || block_given?
|
27
31
|
opts = {store: true}.merge(opts)
|
@@ -54,7 +58,7 @@ module Excursion
|
|
54
58
|
raise ArgumentError, "you must provide at minimum a hash with a :name key" unless app_hash.is_a?(Hash) && app_hash.has_key?(:name)
|
55
59
|
opts = {store: true}.merge(opts)
|
56
60
|
|
57
|
-
app_hash =
|
61
|
+
app_hash = app_hash_defaults.merge(app_hash)
|
58
62
|
name = app_hash[:name]
|
59
63
|
|
60
64
|
if opts[:store]
|
@@ -77,23 +81,39 @@ module Excursion
|
|
77
81
|
raise NoDatastoreError, "You must configure excursion with a datastore." if Excursion.configuration.datastore.nil?
|
78
82
|
require "excursion/datastores/#{Excursion.configuration.datastore.to_s}"
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
84
|
+
send "#{Excursion.configuration.datastore.to_sym}_datastore"
|
85
|
+
end
|
86
|
+
|
87
|
+
def self.datastore_class(type)
|
88
|
+
"Excursion::Datastores::#{type.to_s.capitalize}".constantize
|
89
|
+
end
|
90
|
+
|
91
|
+
def self.simple_datastore(type, config_opt)
|
92
|
+
raise DatastoreConfigurationError, "You must configure the :#{type.to_s} datastore with a #{config_opt.to_s}" if Excursion.configuration.send(config_opt.to_sym).nil?
|
93
|
+
@@datastore ||= datastore_class(type).new(Excursion.configuration.send(config_opt.to_sym))
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.file_datastore
|
97
|
+
simple_datastore(:file, :datastore_file)
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.memcache_datastore
|
101
|
+
simple_datastore(:memcache, :memcache_server)
|
102
|
+
end
|
103
|
+
|
104
|
+
def self.active_record_datastore
|
105
|
+
raise TableDoesNotExist, "To use the :active_record datastore you must first run `rails generate excursion:active_record` followed by `rake db:migrate` to create the storage table" unless Excursion::RoutePool.table_exists?
|
106
|
+
@@datastore ||= Excursion::Datastores::ActiveRecord.new
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.active_record_with_memcache_datastore
|
110
|
+
raise MemcacheConfigurationError, "You must configure the :active_record_with_memcache datastore with a memcache_server" if Excursion.configuration.memcache_server.nil?
|
111
|
+
raise TableDoesNotExist, "To use the :active_record_with_memcache datastore you must first run `rails generate excursion:active_record` followed by `rake db:migrate` to create the storage table" unless Excursion::RoutePool.table_exists?
|
112
|
+
@@datastore ||= Excursion::Datastores::ActiveRecord.new(Excursion.configuration.memcache_server)
|
113
|
+
end
|
114
|
+
|
115
|
+
def self.test_datastore
|
95
116
|
@@datastore ||= Excursion::Datastores::Test.new
|
96
|
-
end
|
97
117
|
end
|
98
118
|
|
99
119
|
def self.pool_updated
|
@@ -45,7 +45,7 @@ module Excursion
|
|
45
45
|
|
46
46
|
def from_cache(cached)
|
47
47
|
@routes = routes_from_cache(cached[:routes]) if cached.has_key?(:routes)
|
48
|
-
@default_url_options = cached[:default_url_options]
|
48
|
+
@default_url_options = cached[:default_url_options] || {}
|
49
49
|
@registered_at = (Time.at(cached[:registered_at]) rescue Time.now)
|
50
50
|
end
|
51
51
|
|
data/lib/excursion/railtie.rb
CHANGED
@@ -1,9 +1,5 @@
|
|
1
1
|
module Excursion
|
2
2
|
class Railtie < Rails::Railtie
|
3
|
-
initializer "excursion.asset_middleware" do |app|
|
4
|
-
app.config.middleware.use "Excursion::AssetMiddleware"
|
5
|
-
end
|
6
|
-
|
7
3
|
config.after_initialize do |app|
|
8
4
|
# Do not register on init when running a generator (is there a better way to detect this? Maybe $0 == 'rails' && ARGV.include?('generate') or 'g')
|
9
5
|
# Do not register on init when running a rake task
|
@@ -12,6 +8,8 @@ module Excursion
|
|
12
8
|
Excursion::Pool.register_application(app)
|
13
9
|
end
|
14
10
|
|
11
|
+
ActionController::Base.send :include, Excursion::Builders::ApplicationBuilder
|
12
|
+
ActionView::Base.send :include, Excursion::Builders::ApplicationBuilder
|
15
13
|
ActionController::Base.send :include, Excursion::CORS if Excursion.configuration.enable_cors
|
16
14
|
end
|
17
15
|
|
@@ -26,7 +24,7 @@ module Excursion
|
|
26
24
|
desc "Remove this app and it's routes from the route pool"
|
27
25
|
task :remove => :environment do
|
28
26
|
Excursion::Pool.remove_application(Rails.application)
|
29
|
-
puts "
|
27
|
+
puts "Removed application #{app.name} from the #{Rails.env} route pool."
|
30
28
|
end
|
31
29
|
end
|
32
30
|
end
|
data/lib/excursion/version.rb
CHANGED
@@ -3,62 +3,18 @@ require File.expand_path('../boot', __FILE__)
|
|
3
3
|
require 'rails/all'
|
4
4
|
|
5
5
|
if defined?(Bundler)
|
6
|
-
|
7
|
-
Bundler.require(*Rails.groups(:assets => %w(development test)))
|
8
|
-
# If you want your assets lazily compiled in production, use this line
|
9
|
-
# Bundler.require(:default, :assets, Rails.env)
|
6
|
+
Bundler.require(:default, :assets, Rails.env)
|
10
7
|
end
|
11
8
|
|
12
9
|
require 'excursion'
|
13
10
|
|
14
11
|
module Dummy
|
15
12
|
class Application < Rails::Application
|
16
|
-
# Settings in config/environments/* take precedence over those specified here.
|
17
|
-
# Application configuration should go into files in config/initializers
|
18
|
-
# -- all .rb files in that directory are automatically loaded.
|
19
|
-
|
20
|
-
# Custom directories with classes and modules you want to be autoloadable.
|
21
|
-
# config.autoload_paths += %W(#{config.root}/extras)
|
22
|
-
|
23
|
-
# Only load the plugins named here, in the order given (default is alphabetical).
|
24
|
-
# :all can be used as a placeholder for all plugins not explicitly named.
|
25
|
-
# config.plugins = [ :exception_notification, :ssl_requirement, :all ]
|
26
|
-
|
27
|
-
# Activate observers that should always be running.
|
28
|
-
# config.active_record.observers = :cacher, :garbage_collector, :forum_observer
|
29
|
-
|
30
|
-
# Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
|
31
|
-
# Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
|
32
|
-
# config.time_zone = 'Central Time (US & Canada)'
|
33
|
-
|
34
|
-
# The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
|
35
|
-
# config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
|
36
|
-
# config.i18n.default_locale = :de
|
37
|
-
|
38
13
|
# Configure the default encoding used in templates for Ruby 1.9.
|
39
14
|
config.encoding = "utf-8"
|
40
15
|
|
41
16
|
# Configure sensitive parameters which will be filtered from the log file.
|
42
17
|
config.filter_parameters += [:password]
|
43
18
|
|
44
|
-
# Enable escaping HTML in JSON.
|
45
|
-
config.active_support.escape_html_entities_in_json = true
|
46
|
-
|
47
|
-
# Use SQL instead of Active Record's schema dumper when creating the database.
|
48
|
-
# This is necessary if your schema can't be completely dumped by the schema dumper,
|
49
|
-
# like if you have constraints or database-specific column types
|
50
|
-
# config.active_record.schema_format = :sql
|
51
|
-
|
52
|
-
# Enforce whitelist mode for mass assignment.
|
53
|
-
# This will create an empty whitelist of attributes available for mass-assignment for all models
|
54
|
-
# in your app. As such, your models will need to explicitly whitelist or blacklist accessible
|
55
|
-
# parameters by using an attr_accessible or attr_protected declaration.
|
56
|
-
#config.active_record.whitelist_attributes = true
|
57
|
-
|
58
|
-
# Enable the asset pipeline
|
59
|
-
config.assets.enabled = true
|
60
|
-
|
61
|
-
# Version of your assets, change this if you want to expire all your assets
|
62
|
-
config.assets.version = '1.0'
|
63
19
|
end
|
64
20
|
end
|
@@ -26,10 +26,4 @@ Dummy::Application.configure do
|
|
26
26
|
# Log the query plan for queries taking more than this (works
|
27
27
|
# with SQLite, MySQL, and PostgreSQL)
|
28
28
|
#config.active_record.auto_explain_threshold_in_seconds = 0.5
|
29
|
-
|
30
|
-
# Do not compress assets
|
31
|
-
config.assets.compress = false
|
32
|
-
|
33
|
-
# Expands the lines which load the assets
|
34
|
-
config.assets.debug = true
|
35
29
|
end
|
@@ -7,61 +7,11 @@ Dummy::Application.configure do
|
|
7
7
|
# Full error reports are disabled and caching is turned on
|
8
8
|
config.consider_all_requests_local = false
|
9
9
|
config.action_controller.perform_caching = true
|
10
|
-
|
11
|
-
# Disable Rails's static asset server (Apache or nginx will already do this)
|
12
|
-
config.serve_static_assets = false
|
13
|
-
|
14
|
-
# Compress JavaScripts and CSS
|
15
|
-
config.assets.compress = true
|
16
|
-
|
17
|
-
# Don't fallback to assets pipeline if a precompiled asset is missed
|
18
|
-
config.assets.compile = false
|
19
|
-
|
20
|
-
# Generate digests for assets URLs
|
21
|
-
config.assets.digest = true
|
22
|
-
|
23
|
-
# Defaults to nil and saved in location specified by config.assets.prefix
|
24
|
-
# config.assets.manifest = YOUR_PATH
|
25
|
-
|
26
|
-
# Specifies the header that your server uses for sending files
|
27
|
-
# config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
|
28
|
-
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
|
29
|
-
|
30
|
-
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
31
|
-
# config.force_ssl = true
|
32
|
-
|
33
|
-
# See everything in the log (default is :info)
|
34
|
-
# config.log_level = :debug
|
35
|
-
|
36
|
-
# Prepend all log lines with the following tags
|
37
|
-
# config.log_tags = [ :subdomain, :uuid ]
|
38
|
-
|
39
|
-
# Use a different logger for distributed setups
|
40
|
-
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
41
|
-
|
42
|
-
# Use a different cache store in production
|
43
|
-
# config.cache_store = :mem_cache_store
|
44
|
-
|
45
|
-
# Enable serving of images, stylesheets, and JavaScripts from an asset server
|
46
|
-
# config.action_controller.asset_host = "http://assets.example.com"
|
47
|
-
|
48
|
-
# Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
|
49
|
-
# config.assets.precompile += %w( search.js )
|
50
|
-
|
51
|
-
# Disable delivery errors, bad email addresses will be ignored
|
52
|
-
# config.action_mailer.raise_delivery_errors = false
|
53
|
-
|
54
|
-
# Enable threaded mode
|
55
|
-
# config.threadsafe!
|
56
|
-
|
10
|
+
|
57
11
|
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
58
12
|
# the I18n.default_locale when a translation can not be found)
|
59
13
|
config.i18n.fallbacks = true
|
60
14
|
|
61
15
|
# Send deprecation notices to registered listeners
|
62
16
|
config.active_support.deprecation = :notify
|
63
|
-
|
64
|
-
# Log the query plan for queries taking more than this (works
|
65
|
-
# with SQLite, MySQL, and PostgreSQL)
|
66
|
-
# config.active_record.auto_explain_threshold_in_seconds = 0.5
|
67
17
|
end
|
@@ -8,10 +8,6 @@ Dummy::Application.configure do
|
|
8
8
|
config.cache_classes = true
|
9
9
|
config.eager_load = false
|
10
10
|
|
11
|
-
# Configure static asset server for tests with Cache-Control for performance
|
12
|
-
config.serve_static_assets = true
|
13
|
-
config.static_cache_control = "public, max-age=3600"
|
14
|
-
|
15
11
|
# Show full error reports and disable caching
|
16
12
|
config.consider_all_requests_local = true
|
17
13
|
config.action_controller.perform_caching = false
|
@@ -27,9 +23,6 @@ Dummy::Application.configure do
|
|
27
23
|
# ActionMailer::Base.deliveries array.
|
28
24
|
config.action_mailer.delivery_method = :test
|
29
25
|
|
30
|
-
# Raise exception on mass assignment protection for Active Record models
|
31
|
-
#config.active_record.mass_assignment_sanitizer = :strict
|
32
|
-
|
33
26
|
# Print deprecation notices to the stderr
|
34
27
|
config.active_support.deprecation = :stderr
|
35
28
|
end
|