padrino-core 0.11.4 → 0.12.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/padrino-core/application/authenticity_token.rb +25 -0
- data/lib/padrino-core/application/rendering/extensions/erubis.rb +11 -7
- data/lib/padrino-core/application/rendering/extensions/haml.rb +3 -2
- data/lib/padrino-core/application/rendering/extensions/slim.rb +10 -3
- data/lib/padrino-core/application/rendering.rb +13 -5
- data/lib/padrino-core/application/routing.rb +62 -19
- data/lib/padrino-core/application.rb +136 -50
- data/lib/padrino-core/cli/base.rb +32 -1
- data/lib/padrino-core/loader.rb +68 -68
- data/lib/padrino-core/logger.rb +6 -6
- data/lib/padrino-core/mounter.rb +9 -4
- data/lib/padrino-core/reloader/rack.rb +26 -0
- data/lib/padrino-core/reloader/storage.rb +55 -0
- data/lib/padrino-core/reloader.rb +192 -287
- data/lib/padrino-core/router.rb +11 -12
- data/lib/padrino-core/server.rb +5 -0
- data/lib/padrino-core/support_lite.rb +31 -32
- data/lib/padrino-core/version.rb +1 -1
- data/lib/padrino-core.rb +22 -30
- data/padrino-core.gemspec +2 -1
- data/test/fixtures/apps/helpers/system_helpers.rb +8 -0
- data/test/fixtures/apps/kiq.rb +3 -0
- data/test/fixtures/apps/lib/myklass/mysubklass.rb +4 -0
- data/test/fixtures/apps/lib/myklass.rb +2 -0
- data/test/fixtures/apps/models/child.rb +2 -0
- data/test/fixtures/apps/models/parent.rb +5 -0
- data/test/fixtures/apps/render.rb +13 -0
- data/test/fixtures/apps/system.rb +13 -0
- data/test/fixtures/apps/views/blog/post.erb +1 -0
- data/test/helper.rb +1 -1
- data/test/mini_shoulda.rb +4 -4
- data/test/test_application.rb +5 -13
- data/test/test_core.rb +2 -6
- data/test/test_csrf_protection.rb +67 -1
- data/test/test_dependencies.rb +14 -1
- data/test/test_mounter.rb +50 -6
- data/test/test_reloader_complex.rb +2 -2
- data/test/test_reloader_simple.rb +1 -1
- data/test/test_reloader_system.rb +52 -0
- data/test/test_rendering.rb +54 -0
- data/test/test_router.rb +121 -2
- data/test/test_routing.rb +84 -15
- metadata +29 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 07676eda48ccc772dcca11b4d6ebe2267cb86fe9
|
4
|
+
data.tar.gz: 669c9795dd7cd5eab46986a28fed64ea87400311
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a4b95dfbdd3ea29423c1f09424ac28a4fce32e08732830b739b08ec159d6205f84f423a04224c9b17ed889c5b4d6850678e94943f8960c6ee94ad2fe8cf69709
|
7
|
+
data.tar.gz: 3c5da6330346fe9950be1bb42dc706c4bca7e682e452d42c7d1c9e6fc18f82b71c482c7eceaaac2838285db1629bf8ecab76d04061201e00afa4b7edc070237f
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Padrino
|
2
|
+
class AuthenticityToken < Rack::Protection::AuthenticityToken
|
3
|
+
def initialize(app, options = {})
|
4
|
+
@app = app
|
5
|
+
@except = options[:except]
|
6
|
+
@except = Array(@except) unless @except.is_a?(Proc)
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def call(env)
|
11
|
+
if except?(env)
|
12
|
+
@app.call(env)
|
13
|
+
else
|
14
|
+
super(env)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def except?(env)
|
19
|
+
return false unless @except
|
20
|
+
path_info = env['PATH_INFO']
|
21
|
+
@except.is_a?(Proc) ? @except.call(env) : @except.any?{|path|
|
22
|
+
path.is_a?(Regexp) ? path.match(path_info) : path == path_info }
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -40,15 +40,18 @@ begin
|
|
40
40
|
def render(*args)
|
41
41
|
app = args.first
|
42
42
|
app_class = app.class
|
43
|
-
@
|
44
|
-
|
43
|
+
@is_padrino_app = app.kind_of?(Padrino::Application) ||
|
44
|
+
(app_class.respond_to?(:erb) && app_class.erb[:engine_class] == Padrino::Erubis::SafeBufferTemplate)
|
45
45
|
super
|
46
46
|
end
|
47
47
|
|
48
|
+
##
|
49
|
+
# In preamble we need a flag `__in_erb_template` and SafeBuffer for padrino apps.
|
50
|
+
#
|
48
51
|
def precompiled_preamble(locals)
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
+
original = super
|
53
|
+
return original unless @is_padrino_app
|
54
|
+
"__in_erb_template = true\n" << original.rpartition("\n").first << "#{@outvar} = _buf = ActiveSupport::SafeBuffer.new\n"
|
52
55
|
end
|
53
56
|
end
|
54
57
|
end
|
@@ -57,8 +60,9 @@ begin
|
|
57
60
|
Tilt.prefer(Padrino::Erubis::Template, :erb)
|
58
61
|
|
59
62
|
if defined? Padrino::Rendering
|
60
|
-
Padrino::Rendering.engine_configurations[:erb] =
|
61
|
-
|
63
|
+
Padrino::Rendering.engine_configurations[:erb] = {
|
64
|
+
:engine_class => Padrino::Erubis::SafeBufferTemplate,
|
65
|
+
}
|
62
66
|
end
|
63
67
|
rescue LoadError
|
64
68
|
end
|
@@ -17,8 +17,9 @@ begin
|
|
17
17
|
end
|
18
18
|
|
19
19
|
if defined? Padrino::Rendering
|
20
|
-
Padrino::Rendering.engine_configurations[:haml] =
|
21
|
-
|
20
|
+
Padrino::Rendering.engine_configurations[:haml] = {
|
21
|
+
:escape_html => true,
|
22
|
+
}
|
22
23
|
|
23
24
|
class Tilt::HamlTemplate
|
24
25
|
include Padrino::Rendering::SafeTemplate
|
@@ -2,12 +2,19 @@ begin
|
|
2
2
|
require 'slim'
|
3
3
|
|
4
4
|
if defined? Padrino::Rendering
|
5
|
-
Padrino::Rendering.engine_configurations[:slim] =
|
6
|
-
|
7
|
-
:buffer => "@_out_buf",
|
5
|
+
Padrino::Rendering.engine_configurations[:slim] = {
|
6
|
+
:generator => Temple::Generators::RailsOutputBuffer,
|
7
|
+
:buffer => "@_out_buf",
|
8
|
+
:use_html_safe => true,
|
9
|
+
:disable_capture => true,
|
10
|
+
}
|
8
11
|
|
9
12
|
class Slim::Template
|
10
13
|
include Padrino::Rendering::SafeTemplate
|
14
|
+
|
15
|
+
def precompiled_preamble(locals)
|
16
|
+
"__in_slim_template = true\n" << super
|
17
|
+
end
|
11
18
|
end
|
12
19
|
end
|
13
20
|
rescue LoadError
|
@@ -195,14 +195,16 @@ module Padrino
|
|
195
195
|
options[:layout] = @layout if options[:layout].nil? || options[:layout] == true
|
196
196
|
# Resolve layouts similar to in Rails
|
197
197
|
if options[:layout].nil? && !settings.templates.has_key?(:layout)
|
198
|
-
layout_path
|
198
|
+
layout_path = settings.fetch_layout_path(options[:layout])
|
199
|
+
is_included_extension = %w[.slim .erb .haml].include?(File.extname(layout_path.to_s))
|
200
|
+
layout_path, layout_engine = *(is_included_extension ? resolve_template(layout_path) : resolved_layout)
|
199
201
|
|
200
202
|
# We need to force layout false so sinatra don't try to render it
|
201
203
|
options[:layout] = layout_path || false
|
202
|
-
options[:layout] = false unless
|
204
|
+
options[:layout] = false unless is_included_extension ? layout_engine : layout_engine == engine
|
203
205
|
options[:layout_engine] = layout_engine || engine if options[:layout]
|
204
206
|
elsif options[:layout].present?
|
205
|
-
options[:layout] = settings.fetch_layout_path(options[:layout]
|
207
|
+
options[:layout], options[:layout_engine] = *resolve_template(settings.fetch_layout_path(options[:layout]))
|
206
208
|
end
|
207
209
|
# Default to original layout value if none found.
|
208
210
|
options[:layout] ||= layout_was
|
@@ -276,11 +278,17 @@ module Padrino
|
|
276
278
|
view_path = options.delete(:views) || settings.views || "./views"
|
277
279
|
target_extension = File.extname(template_path)[1..-1] || "none" # explicit template extension
|
278
280
|
template_path = template_path.chomp(".#{target_extension}")
|
281
|
+
template_glob =
|
282
|
+
if respond_to?(:request) && request.controller.present?
|
283
|
+
File.join("{,#{request.controller}}", template_path)
|
284
|
+
else
|
285
|
+
template_path
|
286
|
+
end
|
279
287
|
|
280
288
|
# Generate potential template candidates
|
281
|
-
templates = Dir[File.join(view_path,
|
289
|
+
templates = Dir[File.join(view_path, template_glob) + ".*"].map do |file|
|
282
290
|
template_engine = File.extname(file)[1..-1].to_sym # Retrieves engine extension
|
283
|
-
template_file = file.sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
|
291
|
+
template_file = file.squeeze('/').sub(view_path, '').chomp(".#{template_engine}").to_sym # retrieves template filename
|
284
292
|
[template_file, template_engine] unless IGNORE_FILE_PATTERN.any? { |pattern| template_engine.to_s =~ pattern }
|
285
293
|
end
|
286
294
|
|
@@ -15,6 +15,19 @@ class Sinatra::Request
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
##
|
19
|
+
# This patches Sinatra to accept UTF-8 urls on JRuby 1.7.6
|
20
|
+
#
|
21
|
+
if RUBY_ENGINE == 'jruby' && defined?(JRUBY_VERSION) && JRUBY_VERSION > '1.7.4'
|
22
|
+
class Sinatra::Base
|
23
|
+
class << self
|
24
|
+
alias_method :old_generate_method, :generate_method
|
25
|
+
def generate_method(method_name, &block)
|
26
|
+
old_generate_method(method_name.to_sym, &block)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
18
31
|
|
19
32
|
class HttpRouter
|
20
33
|
def rewrite_partial_path_info(env, request); end
|
@@ -61,7 +74,7 @@ class HttpRouter
|
|
61
74
|
class Route
|
62
75
|
VALID_HTTP_VERBS.replace %w[GET POST PUT PATCH DELETE HEAD OPTIONS LINK UNLINK]
|
63
76
|
|
64
|
-
attr_accessor :use_layout, :controller, :action, :cache, :cache_key, :
|
77
|
+
attr_accessor :use_layout, :controller, :action, :cache, :cache_key, :cache_expires, :parent
|
65
78
|
|
66
79
|
def before_filters(&block)
|
67
80
|
@_before_filters ||= []
|
@@ -172,6 +185,7 @@ class HttpRouter
|
|
172
185
|
env['router.request'] = request
|
173
186
|
env['router.params'] ||= {}
|
174
187
|
#{"env['router.params'].merge!(Hash[#{param_names.inspect}.zip(request.params)])" if dynamic?}
|
188
|
+
env['router.params'] = env['router.params'].with_indifferent_access
|
175
189
|
@router.rewrite#{"_partial" if route.match_partially}_path_info(env, request)
|
176
190
|
response = @router.process_destination_path(#{path_ivar}, env)
|
177
191
|
return response unless router.pass_on_response(response)
|
@@ -193,7 +207,7 @@ module Padrino
|
|
193
207
|
def apply?(request)
|
194
208
|
detect = @args.any? do |arg|
|
195
209
|
case arg
|
196
|
-
when Symbol then request.route_obj && (request.route_obj.name == arg or request.route_obj.name == [@scoped_controller, arg].flatten.join("
|
210
|
+
when Symbol then request.route_obj && (request.route_obj.name == arg or request.route_obj.name == [@scoped_controller, arg].flatten.join(" ").to_sym)
|
197
211
|
else arg === request.path_info
|
198
212
|
end
|
199
213
|
end || @options.any? do |name, val|
|
@@ -557,7 +571,7 @@ module Padrino
|
|
557
571
|
def url(*args)
|
558
572
|
params = args.extract_options! # parameters is hash at end
|
559
573
|
names, params_array = args.partition{|a| a.is_a?(Symbol)}
|
560
|
-
name = names.join("
|
574
|
+
name = names[0, 2].join(" ").to_sym # route name is concatenated with underscores
|
561
575
|
if params.is_a?(Hash)
|
562
576
|
params[:format] = params[:format].to_s unless params[:format].nil?
|
563
577
|
params = value_to_param(params)
|
@@ -568,10 +582,7 @@ module Padrino
|
|
568
582
|
else
|
569
583
|
compiled_router.path(name, *(params_array << params))
|
570
584
|
end
|
571
|
-
url
|
572
|
-
url[0,0] = conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI']
|
573
|
-
url = "/" if url.blank?
|
574
|
-
url
|
585
|
+
rebase_url(url)
|
575
586
|
rescue HttpRouter::InvalidRouteException
|
576
587
|
route_error = "route mapping for url(#{name.inspect}) could not be found!"
|
577
588
|
raise Padrino::Routing::UnrecognizedException.new(route_error)
|
@@ -586,6 +597,17 @@ module Padrino
|
|
586
597
|
route('HEAD', path, *args, &block)
|
587
598
|
end
|
588
599
|
|
600
|
+
def rebase_url(url)
|
601
|
+
if url.start_with?('/')
|
602
|
+
new_url = ''
|
603
|
+
new_url << conform_uri(uri_root) if defined?(uri_root)
|
604
|
+
new_url << conform_uri(ENV['RACK_BASE_URI']) if ENV['RACK_BASE_URI']
|
605
|
+
new_url << url
|
606
|
+
else
|
607
|
+
url.blank? ? '/' : url
|
608
|
+
end
|
609
|
+
end
|
610
|
+
|
589
611
|
private
|
590
612
|
# Parse params from the url method
|
591
613
|
def value_to_param(value)
|
@@ -786,7 +808,7 @@ module Padrino
|
|
786
808
|
name = options.delete(:name) if name.nil? && options.key?(:name)
|
787
809
|
if name
|
788
810
|
controller_name = controller.join("_")
|
789
|
-
name = "#{controller_name}
|
811
|
+
name = "#{controller_name} #{name}".to_sym unless controller_name.blank?
|
790
812
|
end
|
791
813
|
|
792
814
|
# Merge in option defaults.
|
@@ -859,6 +881,7 @@ module Padrino
|
|
859
881
|
mime_types = types.map { |t| mime_type(t) }.compact
|
860
882
|
url_format = params[:format].to_sym if params[:format]
|
861
883
|
accepts = request.accept.map(&:to_str)
|
884
|
+
accepts = [] if accepts == ["*/*"]
|
862
885
|
|
863
886
|
# Per rfc2616-sec14:
|
864
887
|
# Assume */* if no ACCEPT header is given.
|
@@ -890,7 +913,12 @@ module Padrino
|
|
890
913
|
|
891
914
|
if matched_format
|
892
915
|
@_content_type = url_format || accept_format || :html
|
893
|
-
|
916
|
+
|
917
|
+
if @_content_type != :json
|
918
|
+
content_type(@_content_type, :charset => 'utf-8')
|
919
|
+
else
|
920
|
+
content_type(@_content_type)
|
921
|
+
end
|
894
922
|
end
|
895
923
|
|
896
924
|
matched_format
|
@@ -924,17 +952,24 @@ module Padrino
|
|
924
952
|
# url(:show, :id => 1)
|
925
953
|
# url(:show, :name => :test)
|
926
954
|
# url(:show, 1)
|
927
|
-
# url("/foo")
|
955
|
+
# url("/foo", false, false)
|
928
956
|
#
|
929
957
|
# @see Padrino::Routing::ClassMethods#url
|
930
958
|
#
|
931
959
|
def url(*args)
|
932
|
-
|
933
|
-
|
934
|
-
|
935
|
-
|
936
|
-
|
937
|
-
|
960
|
+
if args.first.is_a?(String)
|
961
|
+
url_path = settings.rebase_url(args.shift)
|
962
|
+
if args.empty?
|
963
|
+
url_path
|
964
|
+
else
|
965
|
+
# Delegate sinatra-style urls to Sinatra. Ex: url("/foo", false, false)
|
966
|
+
# http://www.sinatrarb.com/intro#Generating%20URLs
|
967
|
+
super url_path, *args
|
968
|
+
end
|
969
|
+
else
|
970
|
+
# Delegate to Padrino named route URL generation.
|
971
|
+
settings.url(*args)
|
972
|
+
end
|
938
973
|
end
|
939
974
|
alias :url_for :url
|
940
975
|
|
@@ -944,9 +979,15 @@ module Padrino
|
|
944
979
|
# @example
|
945
980
|
# absolute_url(:show, :id => 1) # => http://example.com/show?id=1
|
946
981
|
# absolute_url(:show, 24) # => https://example.com/admin/show/24
|
982
|
+
# absolute_url('/foo/bar') # => https://example.com/admin/foo/bar
|
983
|
+
# absolute_url('baz') # => https://example.com/admin/foo/baz
|
947
984
|
#
|
948
|
-
def absolute_url(
|
949
|
-
|
985
|
+
def absolute_url(*args)
|
986
|
+
url_path = args.shift
|
987
|
+
if url_path.is_a?(String) && !url_path.start_with?('/')
|
988
|
+
url_path = request.env['PATH_INFO'].rpartition('/').first << '/' << url_path
|
989
|
+
end
|
990
|
+
uri url(url_path, *args), true, false
|
950
991
|
end
|
951
992
|
|
952
993
|
def recognize_path(path)
|
@@ -958,10 +999,12 @@ module Padrino
|
|
958
999
|
#
|
959
1000
|
def current_path(*path_params)
|
960
1001
|
if path_params.last.is_a?(Hash)
|
961
|
-
path_params[-1] = params.merge(path_params[-1])
|
1002
|
+
path_params[-1] = params.merge(path_params[-1].with_indifferent_access)
|
962
1003
|
else
|
963
1004
|
path_params << params
|
964
1005
|
end
|
1006
|
+
|
1007
|
+
path_params[-1] = path_params[-1].symbolize_keys
|
965
1008
|
@route.path(*path_params)
|
966
1009
|
end
|
967
1010
|
|
@@ -2,11 +2,9 @@ require 'padrino-core/application/flash'
|
|
2
2
|
require 'padrino-core/application/rendering'
|
3
3
|
require 'padrino-core/application/routing'
|
4
4
|
require 'padrino-core/application/showexceptions'
|
5
|
+
require 'padrino-core/application/authenticity_token'
|
5
6
|
|
6
7
|
module Padrino
|
7
|
-
class ApplicationSetupError < RuntimeError
|
8
|
-
end
|
9
|
-
|
10
8
|
##
|
11
9
|
# Subclasses of this become independent Padrino applications
|
12
10
|
# (stemming from Sinatra::Application).
|
@@ -26,20 +24,24 @@ module Padrino
|
|
26
24
|
Padrino.logger
|
27
25
|
end
|
28
26
|
|
27
|
+
# TODO: Remove this hack after getting rid of thread-unsafe http_router:
|
28
|
+
alias_method :original_call, :call
|
29
|
+
def call(*args)
|
30
|
+
settings.init_mutex.synchronize do
|
31
|
+
instance_eval{ undef :call }
|
32
|
+
class_eval{ alias_method :call, :original_call }
|
33
|
+
instance_eval{ undef :original_call }
|
34
|
+
super(*args)
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
29
38
|
class << self
|
30
39
|
def inherited(base)
|
31
40
|
begun_at = Time.now
|
32
41
|
CALLERS_TO_IGNORE.concat(PADRINO_IGNORE_CALLERS)
|
33
42
|
base.default_configuration!
|
34
|
-
base.prerequisites.concat([
|
35
|
-
File.join(base.root, '/models.rb'),
|
36
|
-
File.join(base.root, '/models/**/*.rb'),
|
37
|
-
File.join(base.root, '/lib.rb'),
|
38
|
-
File.join(base.root, '/lib/**/*.rb')
|
39
|
-
]).uniq!
|
40
|
-
Padrino.require_dependencies(base.prerequisites)
|
41
43
|
logger.devel :setup, begun_at, base
|
42
|
-
super(base)
|
44
|
+
super(base)
|
43
45
|
end
|
44
46
|
|
45
47
|
##
|
@@ -54,10 +56,10 @@ module Padrino
|
|
54
56
|
# MyApp.reload!
|
55
57
|
#
|
56
58
|
def reload!
|
57
|
-
logger.devel "Reloading #{settings}"
|
59
|
+
logger.devel "Reloading application #{settings}"
|
58
60
|
reset!
|
59
61
|
reset_router!
|
60
|
-
Padrino.require_dependencies(settings.app_file, :force => true)
|
62
|
+
Padrino.require_dependencies(settings.app_file, :force => true)
|
61
63
|
require_dependencies
|
62
64
|
default_filters!
|
63
65
|
default_routes!
|
@@ -90,6 +92,26 @@ module Padrino
|
|
90
92
|
router.routes
|
91
93
|
end
|
92
94
|
|
95
|
+
##
|
96
|
+
# Returns an absolute path of view in application views folder.
|
97
|
+
#
|
98
|
+
# @example
|
99
|
+
# Admin.view_path 'users/index' #=> "/home/user/test/admin/views/users/index"
|
100
|
+
#
|
101
|
+
def view_path(view)
|
102
|
+
File.expand_path(view, views)
|
103
|
+
end
|
104
|
+
|
105
|
+
##
|
106
|
+
# Returns an absolute path of application layout.
|
107
|
+
#
|
108
|
+
# @example
|
109
|
+
# Admin.layout_path :application #=> "/home/user/test/admin/views/layouts/application"
|
110
|
+
#
|
111
|
+
def layout_path(layout)
|
112
|
+
view_path("layouts/#{layout}")
|
113
|
+
end
|
114
|
+
|
93
115
|
##
|
94
116
|
# Setup the application by registering initializers, load paths and logger.
|
95
117
|
# Invoked automatically when an application is first instantiated.
|
@@ -103,11 +125,11 @@ module Padrino
|
|
103
125
|
settings.default_routes!
|
104
126
|
settings.default_errors!
|
105
127
|
if defined?(I18n)
|
128
|
+
Reloader.special_files += settings.locale_path
|
106
129
|
I18n.load_path << settings.locale_path
|
107
130
|
I18n.reload!
|
108
131
|
end
|
109
132
|
@_configured = true
|
110
|
-
@_configured
|
111
133
|
end
|
112
134
|
|
113
135
|
##
|
@@ -127,7 +149,13 @@ module Padrino
|
|
127
149
|
# directory that need to be added to +$LOAD_PATHS+ from this application
|
128
150
|
#
|
129
151
|
def load_paths
|
130
|
-
@_load_paths ||=
|
152
|
+
@_load_paths ||= [
|
153
|
+
'models',
|
154
|
+
'lib',
|
155
|
+
'mailers',
|
156
|
+
'controllers',
|
157
|
+
'helpers',
|
158
|
+
].map { |path| File.join(settings.root, path) }
|
131
159
|
end
|
132
160
|
|
133
161
|
##
|
@@ -143,8 +171,14 @@ module Padrino
|
|
143
171
|
#
|
144
172
|
def dependencies
|
145
173
|
[
|
146
|
-
'urls.rb',
|
147
|
-
'
|
174
|
+
'urls.rb',
|
175
|
+
'config/urls.rb',
|
176
|
+
'mailers/*.rb',
|
177
|
+
'mailers.rb',
|
178
|
+
'controllers/**/*.rb',
|
179
|
+
'controllers.rb',
|
180
|
+
'helpers/**/*.rb',
|
181
|
+
'helpers.rb',
|
148
182
|
].map { |file| Dir[File.join(settings.root, file)] }.flatten
|
149
183
|
end
|
150
184
|
|
@@ -168,37 +202,62 @@ module Padrino
|
|
168
202
|
end
|
169
203
|
|
170
204
|
protected
|
205
|
+
|
171
206
|
##
|
172
207
|
# Defines default settings for Padrino application.
|
173
208
|
#
|
174
209
|
def default_configuration!
|
175
|
-
|
176
|
-
set :
|
210
|
+
set :app_file, File.expand_path(caller_files.first || $0)
|
211
|
+
set :app_name, settings.to_s.underscore.to_sym
|
212
|
+
|
177
213
|
set :environment, Padrino.env
|
178
214
|
set :reload, Proc.new { development? }
|
179
215
|
set :logging, Proc.new { development? }
|
216
|
+
|
180
217
|
set :method_override, true
|
181
|
-
set :
|
182
|
-
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
183
|
-
set :views, Proc.new { File.join(root, 'views') }
|
184
|
-
set :images_path, Proc.new { File.join(public_folder, 'images') }
|
185
|
-
set :protection, true
|
218
|
+
set :default_builder, 'StandardFormBuilder'
|
186
219
|
|
187
|
-
|
220
|
+
# TODO: Remove this hack after getting rid of thread-unsafe http_router:
|
221
|
+
set :init_mutex, Mutex.new
|
188
222
|
|
189
|
-
#
|
190
|
-
set :
|
191
|
-
|
192
|
-
|
193
|
-
|
223
|
+
# TODO: Remove this line after sinatra version up.
|
224
|
+
set :add_charset, %w[javascript xml xhtml+xml].map {|t| "application/#{t}" }
|
225
|
+
|
226
|
+
default_paths!
|
227
|
+
default_security!
|
228
|
+
global_configuration!
|
229
|
+
setup_prerequisites!
|
230
|
+
end
|
231
|
+
|
232
|
+
def setup_prerequisites!
|
233
|
+
prerequisites.concat(default_prerequisites).uniq!
|
234
|
+
Padrino.require_dependencies(prerequisites)
|
235
|
+
end
|
194
236
|
|
195
|
-
|
237
|
+
def default_paths!
|
238
|
+
set :locale_path, Proc.new { Dir.glob File.join(root, 'locale/**/*.{rb,yml}') }
|
239
|
+
set :views, Proc.new { File.join(root, 'views') }
|
196
240
|
|
197
|
-
|
241
|
+
set :uri_root, '/'
|
242
|
+
set :public_folder, Proc.new { Padrino.root('public', uri_root) }
|
243
|
+
set :images_path, Proc.new { File.join(public_folder, 'images') }
|
244
|
+
end
|
245
|
+
|
246
|
+
def default_security!
|
247
|
+
set :protection, :except => :path_traversal
|
248
|
+
set :authentication, false
|
249
|
+
set :sessions, false
|
198
250
|
set :protect_from_csrf, false
|
199
251
|
set :allow_disabled_csrf, false
|
200
|
-
|
201
|
-
|
252
|
+
end
|
253
|
+
|
254
|
+
##
|
255
|
+
# Applies global padrino configuration blocks to current application.
|
256
|
+
#
|
257
|
+
def global_configuration!
|
258
|
+
Padrino.global_configurations.each do |configuration|
|
259
|
+
class_eval(&configuration)
|
260
|
+
end
|
202
261
|
end
|
203
262
|
|
204
263
|
##
|
@@ -220,9 +279,7 @@ module Padrino
|
|
220
279
|
#
|
221
280
|
def default_filters!
|
222
281
|
before do
|
223
|
-
unless @_content_type
|
224
|
-
response['Content-Type'] = 'text/html;charset=utf-8'
|
225
|
-
end
|
282
|
+
response['Content-Type'] = 'text/html;charset=utf-8' unless @_content_type
|
226
283
|
end
|
227
284
|
end
|
228
285
|
|
@@ -249,7 +306,20 @@ module Padrino
|
|
249
306
|
Padrino.require_dependencies(dependencies, :force => true)
|
250
307
|
end
|
251
308
|
|
309
|
+
##
|
310
|
+
# Returns globs of default paths of application prerequisites.
|
311
|
+
#
|
312
|
+
def default_prerequisites
|
313
|
+
[
|
314
|
+
'/models.rb',
|
315
|
+
'/models/**/*.rb',
|
316
|
+
'/lib.rb',
|
317
|
+
'/lib/**/*.rb',
|
318
|
+
].map{ |glob| File.join(settings.root, glob) }
|
319
|
+
end
|
320
|
+
|
252
321
|
private
|
322
|
+
|
253
323
|
# Overrides the default middleware for Sinatra based on Padrino conventions.
|
254
324
|
# Also initializes the application after setting up the middleware.
|
255
325
|
def setup_default_middleware(builder)
|
@@ -267,6 +337,34 @@ module Padrino
|
|
267
337
|
|
268
338
|
# sets up csrf protection for the app:
|
269
339
|
def setup_csrf_protection(builder)
|
340
|
+
check_csrf_protection_dependency
|
341
|
+
|
342
|
+
if protect_from_csrf?
|
343
|
+
if protect_from_csrf.is_a?(Hash) && protect_from_csrf[:except]
|
344
|
+
builder.use(AuthenticityToken,
|
345
|
+
options_for_csrf_protection_setup.merge(:except => protect_from_csrf[:except]))
|
346
|
+
else
|
347
|
+
builder.use(Rack::Protection::AuthenticityToken,
|
348
|
+
options_for_csrf_protection_setup)
|
349
|
+
end
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
# returns the options used in the builder for csrf protection setup
|
354
|
+
def options_for_csrf_protection_setup
|
355
|
+
options = { :logger => logger }
|
356
|
+
|
357
|
+
if allow_disabled_csrf?
|
358
|
+
options.merge!({
|
359
|
+
:reaction => :report,
|
360
|
+
:report_key => 'protection.csrf.failed'
|
361
|
+
})
|
362
|
+
end
|
363
|
+
options
|
364
|
+
end
|
365
|
+
|
366
|
+
# throw an exception if the protect_from_csrf is active but sessions not.
|
367
|
+
def check_csrf_protection_dependency
|
270
368
|
if protect_from_csrf? && !sessions?
|
271
369
|
raise(<<-ERROR)
|
272
370
|
`protect_from_csrf` is activated, but `sessions` are not. To enable csrf
|
@@ -277,19 +375,7 @@ protection, use:
|
|
277
375
|
or deactivate protect_from_csrf:
|
278
376
|
|
279
377
|
disable :protect_from_csrf
|
280
|
-
ERROR
|
281
|
-
end
|
282
|
-
|
283
|
-
if protect_from_csrf?
|
284
|
-
if allow_disabled_csrf?
|
285
|
-
builder.use Rack::Protection::AuthenticityToken,
|
286
|
-
:reaction => :report,
|
287
|
-
:report_key => 'protection.csrf.failed',
|
288
|
-
:logger => logger
|
289
|
-
else
|
290
|
-
builder.use Rack::Protection::AuthenticityToken,
|
291
|
-
:logger => logger
|
292
|
-
end
|
378
|
+
ERROR
|
293
379
|
end
|
294
380
|
end
|
295
381
|
end
|
@@ -18,11 +18,19 @@ module Padrino
|
|
18
18
|
method_option :daemonize, :type => :boolean, :aliases => "-d", :desc => "Run daemonized in the background."
|
19
19
|
method_option :pid, :type => :string, :aliases => "-i", :desc => "File to store pid."
|
20
20
|
method_option :debug, :type => :boolean, :desc => "Set debugging flags."
|
21
|
+
method_option :options, :type => :array, :aliases => "-O", :desc => "--options NAME=VALUE NAME2=VALUE2'. pass VALUE to the server as option NAME. If no VALUE, sets it to true. Run '#{$0} --server_options"
|
22
|
+
method_option :server_options, :type => :boolean, :desc => "Tells the current server handler's options that can be used with --options"
|
23
|
+
|
21
24
|
def start
|
22
25
|
prepare :start
|
23
26
|
require File.expand_path("../adapter", __FILE__)
|
24
27
|
require File.expand_path('config/boot.rb')
|
25
|
-
|
28
|
+
|
29
|
+
if options[:server_options]
|
30
|
+
puts server_options(options)
|
31
|
+
else
|
32
|
+
Padrino::Cli::Adapter.start(options)
|
33
|
+
end
|
26
34
|
end
|
27
35
|
|
28
36
|
desc "stop", "Stops the Padrino application (alternatively use 'st')."
|
@@ -124,6 +132,29 @@ module Padrino
|
|
124
132
|
end
|
125
133
|
end
|
126
134
|
|
135
|
+
# https://github.com/rack/rack/blob/master/lib/rack/server.rb\#L100
|
136
|
+
def server_options(options)
|
137
|
+
begin
|
138
|
+
info = []
|
139
|
+
server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
|
140
|
+
if server && server.respond_to?(:valid_options)
|
141
|
+
info << ""
|
142
|
+
info << "Server-specific options for #{server.name}:"
|
143
|
+
|
144
|
+
has_options = false
|
145
|
+
server.valid_options.each do |name, description|
|
146
|
+
next if name.to_s.match(/^(Host|Port)[^a-zA-Z]/) # ignore handler's host and port options, we do our own.
|
147
|
+
info << " -O %-21s %s" % [name, description]
|
148
|
+
has_options = true
|
149
|
+
end
|
150
|
+
return "" if !has_options
|
151
|
+
end
|
152
|
+
info.join("\n")
|
153
|
+
rescue NameError
|
154
|
+
return "Warning: Could not find handler specified (#{options[:server] || 'default'}) to determine handler-specific options"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
127
158
|
protected
|
128
159
|
|
129
160
|
def self.banner(task=nil, *args)
|