actionpack 3.0.0.beta3 → 3.0.0.beta4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +19 -0
- data/lib/abstract_controller.rb +1 -1
- data/lib/abstract_controller/asset_paths.rb +9 -0
- data/lib/abstract_controller/base.rb +5 -13
- data/lib/abstract_controller/callbacks.rb +1 -1
- data/lib/abstract_controller/helpers.rb +0 -1
- data/lib/abstract_controller/layouts.rb +3 -3
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/rendering.rb +1 -0
- data/lib/action_controller/base.rb +5 -1
- data/lib/action_controller/caching.rb +2 -3
- data/lib/action_controller/caching/actions.rb +1 -1
- data/lib/action_controller/caching/fragments.rb +1 -1
- data/lib/action_controller/caching/pages.rb +8 -8
- data/lib/action_controller/caching/sweeping.rb +1 -0
- data/lib/action_controller/deprecated/base.rb +10 -36
- data/lib/action_controller/metal.rb +45 -3
- data/lib/action_controller/metal/compatibility.rb +2 -2
- data/lib/action_controller/metal/helpers.rb +3 -3
- data/lib/action_controller/metal/http_authentication.rb +158 -0
- data/lib/action_controller/metal/instrumentation.rb +5 -5
- data/lib/action_controller/metal/rack_delegation.rb +4 -4
- data/lib/action_controller/metal/renderers.rb +3 -3
- data/lib/action_controller/metal/request_forgery_protection.rb +45 -74
- data/lib/action_controller/metal/responder.rb +1 -1
- data/lib/action_controller/metal/url_for.rb +8 -0
- data/lib/action_controller/railtie.rb +26 -39
- data/lib/action_controller/test_case.rb +147 -135
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +1 -0
- data/lib/action_dispatch.rb +0 -1
- data/lib/action_dispatch/http/parameters.rb +2 -1
- data/lib/action_dispatch/http/request.rb +19 -7
- data/lib/action_dispatch/http/response.rb +3 -33
- data/lib/action_dispatch/middleware/cookies.rb +44 -10
- data/lib/action_dispatch/middleware/flash.rb +11 -1
- data/lib/action_dispatch/middleware/params_parser.rb +3 -1
- data/lib/action_dispatch/middleware/session/abstract_store.rb +47 -83
- data/lib/action_dispatch/middleware/session/cookie_store.rb +19 -165
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +18 -12
- data/lib/action_dispatch/middleware/stack.rb +17 -67
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +1 -1
- data/lib/action_dispatch/railtie.rb +0 -2
- data/lib/action_dispatch/routing/deprecated_mapper.rb +1 -0
- data/lib/action_dispatch/routing/mapper.rb +89 -23
- data/lib/action_dispatch/routing/route_set.rb +22 -16
- data/lib/action_dispatch/routing/url_for.rb +1 -1
- data/lib/action_dispatch/testing/assertions/routing.rb +1 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +11 -7
- data/lib/action_dispatch/testing/test_process.rb +3 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +5 -1
- data/lib/action_view/base.rb +10 -4
- data/lib/action_view/helpers/active_model_helper.rb +1 -8
- data/lib/action_view/helpers/asset_tag_helper.rb +7 -4
- data/lib/action_view/helpers/cache_helper.rb +14 -14
- data/lib/action_view/helpers/capture_helper.rb +25 -6
- data/lib/action_view/helpers/date_helper.rb +33 -44
- data/lib/action_view/helpers/form_helper.rb +47 -27
- data/lib/action_view/helpers/form_options_helper.rb +26 -3
- data/lib/action_view/helpers/form_tag_helper.rb +8 -4
- data/lib/action_view/helpers/number_helper.rb +5 -2
- data/lib/action_view/helpers/prototype_helper.rb +1 -1
- data/lib/action_view/helpers/tag_helper.rb +1 -1
- data/lib/action_view/helpers/text_helper.rb +55 -46
- data/lib/action_view/helpers/translation_helper.rb +19 -8
- data/lib/action_view/helpers/url_helper.rb +2 -4
- data/lib/action_view/locale/en.yml +14 -14
- data/lib/action_view/lookup_context.rb +52 -22
- data/lib/action_view/paths.rb +1 -0
- data/lib/action_view/render/layouts.rb +3 -12
- data/lib/action_view/render/partials.rb +21 -10
- data/lib/action_view/render/rendering.rb +1 -1
- data/lib/action_view/template.rb +172 -26
- data/lib/action_view/template/error.rb +25 -27
- data/lib/action_view/template/handlers.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +92 -45
- data/lib/action_view/template/resolver.rb +4 -1
- data/lib/action_view/test_case.rb +105 -72
- data/lib/action_view/testing/resolvers.rb +43 -0
- metadata +62 -20
- data/lib/abstract_controller/assigns.rb +0 -21
- data/lib/action_dispatch/middleware/cascade.rb +0 -29
@@ -38,9 +38,9 @@ module ActionDispatch
|
|
38
38
|
options = env['rack.session.options']
|
39
39
|
expiry = options[:expire_after] || 0
|
40
40
|
@pool.set(sid, session_data, expiry)
|
41
|
-
|
41
|
+
sid
|
42
42
|
rescue MemCache::MemCacheError, Errno::ECONNREFUSED
|
43
|
-
|
43
|
+
false
|
44
44
|
end
|
45
45
|
end
|
46
46
|
end
|
@@ -6,7 +6,7 @@ module ActionDispatch
|
|
6
6
|
# This middleware rescues any exception returned by the application and renders
|
7
7
|
# nice exception pages if it's being rescued locally.
|
8
8
|
class ShowExceptions
|
9
|
-
LOCALHOST = [
|
9
|
+
LOCALHOST = [/^127\.0\.0\.\d{1,3}$/, "::1", /^0:0:0:0:0:0:0:1(%.*)?$/].freeze
|
10
10
|
|
11
11
|
RESCUES_TEMPLATE_PATH = File.join(File.dirname(__FILE__), 'templates')
|
12
12
|
|
@@ -45,7 +45,17 @@ module ActionDispatch
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def call(env)
|
48
|
-
@app.call(env)
|
48
|
+
status, headers, body = @app.call(env)
|
49
|
+
|
50
|
+
# Only this middleware cares about RoutingError. So, let's just raise
|
51
|
+
# it here.
|
52
|
+
# TODO: refactor this middleware to handle the X-Cascade scenario without
|
53
|
+
# having to raise an exception.
|
54
|
+
if headers['X-Cascade'] == 'pass'
|
55
|
+
raise ActionController::RoutingError, "No route matches #{env['PATH_INFO'].inspect}"
|
56
|
+
end
|
57
|
+
|
58
|
+
[status, headers, body]
|
49
59
|
rescue Exception => exception
|
50
60
|
raise exception if env['action_dispatch.show_exceptions'] == false
|
51
61
|
render_exception(env, exception)
|
@@ -62,7 +72,7 @@ module ActionDispatch
|
|
62
72
|
rescue_action_in_public(exception)
|
63
73
|
end
|
64
74
|
rescue Exception => failsafe_error
|
65
|
-
$stderr.puts "Error during failsafe response: #{failsafe_error}"
|
75
|
+
$stderr.puts "Error during failsafe response: #{failsafe_error}\n #{failsafe_error.backtrace * "\n "}"
|
66
76
|
FAILSAFE_RESPONSE
|
67
77
|
end
|
68
78
|
|
@@ -104,7 +114,7 @@ module ActionDispatch
|
|
104
114
|
|
105
115
|
# True if the request came from localhost, 127.0.0.1.
|
106
116
|
def local_request?(request)
|
107
|
-
LOCALHOST.any?{ |local_ip| request.remote_addr
|
117
|
+
LOCALHOST.any? { |local_ip| local_ip === request.remote_addr && local_ip === request.remote_ip }
|
108
118
|
end
|
109
119
|
|
110
120
|
def status_code(exception)
|
@@ -123,14 +133,10 @@ module ActionDispatch
|
|
123
133
|
return unless logger
|
124
134
|
|
125
135
|
ActiveSupport::Deprecation.silence do
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
"\n#{exception.class} (#{exception.message}):\n " +
|
131
|
-
clean_backtrace(exception).join("\n ") + "\n\n"
|
132
|
-
)
|
133
|
-
end
|
136
|
+
message = "\n#{exception.class} (#{exception.message}):\n"
|
137
|
+
message << exception.annoted_source_code if exception.respond_to?(:annoted_source_code)
|
138
|
+
message << exception.backtrace.join("\n ")
|
139
|
+
logger.fatal("#{message}\n\n")
|
134
140
|
end
|
135
141
|
end
|
136
142
|
|
@@ -3,49 +3,15 @@ require "active_support/inflector/methods"
|
|
3
3
|
module ActionDispatch
|
4
4
|
class MiddlewareStack < Array
|
5
5
|
class Middleware
|
6
|
-
def self.new(klass, *args, &block)
|
7
|
-
if klass.is_a?(self)
|
8
|
-
klass
|
9
|
-
else
|
10
|
-
super
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
6
|
attr_reader :args, :block
|
15
7
|
|
16
|
-
def initialize(
|
17
|
-
@
|
18
|
-
|
19
|
-
options = args.extract_options!
|
20
|
-
if options.has_key?(:if)
|
21
|
-
@conditional = options.delete(:if)
|
22
|
-
else
|
23
|
-
@conditional = true
|
24
|
-
end
|
25
|
-
args << options unless options.empty?
|
26
|
-
|
27
|
-
@args = args
|
28
|
-
@block = block
|
8
|
+
def initialize(klass_or_name, *args, &block)
|
9
|
+
@ref = ActiveSupport::Dependencies::Reference.new(klass_or_name)
|
10
|
+
@args, @block = args, block
|
29
11
|
end
|
30
12
|
|
31
13
|
def klass
|
32
|
-
|
33
|
-
@klass
|
34
|
-
elsif @klass.respond_to?(:call)
|
35
|
-
@klass.call
|
36
|
-
else
|
37
|
-
ActiveSupport::Inflector.constantize(@klass.to_s)
|
38
|
-
end
|
39
|
-
end
|
40
|
-
|
41
|
-
def active?
|
42
|
-
return false unless klass
|
43
|
-
|
44
|
-
if @conditional.respond_to?(:call)
|
45
|
-
@conditional.call
|
46
|
-
else
|
47
|
-
@conditional
|
48
|
-
end
|
14
|
+
@ref.get
|
49
15
|
end
|
50
16
|
|
51
17
|
def ==(middleware)
|
@@ -55,11 +21,7 @@ module ActionDispatch
|
|
55
21
|
when Class
|
56
22
|
klass == middleware
|
57
23
|
else
|
58
|
-
|
59
|
-
normalize(@klass) == normalize(middleware)
|
60
|
-
else
|
61
|
-
klass.name == middleware.to_s
|
62
|
-
end
|
24
|
+
normalize(@ref.name) == normalize(middleware)
|
63
25
|
end
|
64
26
|
end
|
65
27
|
|
@@ -68,25 +30,14 @@ module ActionDispatch
|
|
68
30
|
end
|
69
31
|
|
70
32
|
def build(app)
|
71
|
-
|
72
|
-
klass.new(app, *build_args, &block)
|
73
|
-
else
|
74
|
-
klass.new(app, *build_args)
|
75
|
-
end
|
33
|
+
klass.new(app, *args, &block)
|
76
34
|
end
|
77
35
|
|
78
|
-
|
79
|
-
def lazy_compare?(object)
|
80
|
-
object.is_a?(String) || object.is_a?(Symbol)
|
81
|
-
end
|
82
|
-
|
83
|
-
def normalize(object)
|
84
|
-
object.to_s.strip.sub(/^::/, '')
|
85
|
-
end
|
36
|
+
private
|
86
37
|
|
87
|
-
|
88
|
-
|
89
|
-
|
38
|
+
def normalize(object)
|
39
|
+
object.to_s.strip.sub(/^::/, '')
|
40
|
+
end
|
90
41
|
end
|
91
42
|
|
92
43
|
def initialize(*args, &block)
|
@@ -96,7 +47,7 @@ module ActionDispatch
|
|
96
47
|
|
97
48
|
def insert(index, *args, &block)
|
98
49
|
index = self.index(index) unless index.is_a?(Integer)
|
99
|
-
middleware = Middleware.new(*args, &block)
|
50
|
+
middleware = self.class::Middleware.new(*args, &block)
|
100
51
|
super(index, middleware)
|
101
52
|
end
|
102
53
|
|
@@ -114,20 +65,19 @@ module ActionDispatch
|
|
114
65
|
end
|
115
66
|
|
116
67
|
def use(*args, &block)
|
117
|
-
middleware = Middleware.new(*args, &block)
|
68
|
+
middleware = self.class::Middleware.new(*args, &block)
|
118
69
|
push(middleware)
|
119
70
|
end
|
120
71
|
|
121
72
|
def active
|
122
|
-
|
73
|
+
ActiveSupport::Deprecation.warn "All middlewares in the chaing are active since the laziness " <<
|
74
|
+
"was removed from the middleware stack", caller
|
123
75
|
end
|
124
76
|
|
125
|
-
def build(app = nil, &
|
126
|
-
app ||=
|
127
|
-
|
77
|
+
def build(app = nil, &block)
|
78
|
+
app ||= block
|
128
79
|
raise "MiddlewareStack#build requires an app" unless app
|
129
|
-
|
130
|
-
active.reverse.inject(app) { |a, e| e.build(a) }
|
80
|
+
reverse.inject(app) { |a, e| e.build(a) }
|
131
81
|
end
|
132
82
|
end
|
133
83
|
end
|
@@ -13,7 +13,7 @@
|
|
13
13
|
request_dump = clean_params.empty? ? 'None' : clean_params.inspect.gsub(',', ",\n")
|
14
14
|
|
15
15
|
def debug_hash(hash)
|
16
|
-
hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect}" }.join("\n")
|
16
|
+
hash.sort_by { |k, v| k.to_s }.map { |k, v| "#{k}: #{v.inspect rescue $!.message}" }.join("\n")
|
17
17
|
end
|
18
18
|
%>
|
19
19
|
|
@@ -10,8 +10,6 @@ module ActionDispatch
|
|
10
10
|
|
11
11
|
# Prepare dispatcher callbacks and run 'prepare' callbacks
|
12
12
|
initializer "action_dispatch.prepare_dispatcher" do |app|
|
13
|
-
# TODO: This used to say unless defined?(Dispatcher). Find out why and fix.
|
14
|
-
require 'rails/dispatcher'
|
15
13
|
ActionDispatch::Callbacks.to_prepare { app.routes_reloader.reload_if_changed }
|
16
14
|
end
|
17
15
|
end
|
@@ -64,10 +64,11 @@ module ActionDispatch
|
|
64
64
|
end
|
65
65
|
|
66
66
|
path = normalize_path(path)
|
67
|
+
path_without_format = path.sub(/\(\.:format\)$/, '')
|
67
68
|
|
68
|
-
if using_match_shorthand?(
|
69
|
-
options[:to] ||=
|
70
|
-
options[:as] ||=
|
69
|
+
if using_match_shorthand?(path_without_format, options)
|
70
|
+
options[:to] ||= path_without_format[1..-1].sub(%r{/([^/]*)$}, '#\1')
|
71
|
+
options[:as] ||= path_without_format[1..-1].gsub("/", "_")
|
71
72
|
end
|
72
73
|
|
73
74
|
[ path, options ]
|
@@ -462,6 +463,10 @@ module ActionDispatch
|
|
462
463
|
name.to_s.singularize
|
463
464
|
end
|
464
465
|
|
466
|
+
def member_prefix
|
467
|
+
':id'
|
468
|
+
end
|
469
|
+
|
465
470
|
def member_name
|
466
471
|
singular
|
467
472
|
end
|
@@ -508,6 +513,10 @@ module ActionDispatch
|
|
508
513
|
end
|
509
514
|
end
|
510
515
|
|
516
|
+
def nested_prefix
|
517
|
+
id_segment
|
518
|
+
end
|
519
|
+
|
511
520
|
def nested_options
|
512
521
|
options = { :name_prefix => member_name }
|
513
522
|
options["#{singular}_id".to_sym] = id_constraint if id_constraint?
|
@@ -531,9 +540,21 @@ module ActionDispatch
|
|
531
540
|
end
|
532
541
|
end
|
533
542
|
|
543
|
+
def member_prefix
|
544
|
+
''
|
545
|
+
end
|
546
|
+
|
534
547
|
def member_name
|
535
548
|
name
|
536
549
|
end
|
550
|
+
|
551
|
+
def nested_prefix
|
552
|
+
''
|
553
|
+
end
|
554
|
+
|
555
|
+
def nested_options
|
556
|
+
{ :name_prefix => member_name }
|
557
|
+
end
|
537
558
|
end
|
538
559
|
|
539
560
|
def initialize(*args) #:nodoc:
|
@@ -543,6 +564,7 @@ module ActionDispatch
|
|
543
564
|
|
544
565
|
def resource(*resources, &block)
|
545
566
|
options = resources.extract_options!
|
567
|
+
options = (@scope[:options] || {}).merge(options)
|
546
568
|
|
547
569
|
if apply_common_behavior_for(:resource, resources, options, &block)
|
548
570
|
return self
|
@@ -553,17 +575,17 @@ module ActionDispatch
|
|
553
575
|
scope(:path => resource.path, :controller => resource.controller) do
|
554
576
|
with_scope_level(:resource, resource) do
|
555
577
|
|
556
|
-
|
557
|
-
yield if block_given?
|
558
|
-
end
|
578
|
+
yield if block_given?
|
559
579
|
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
564
|
-
|
565
|
-
|
566
|
-
|
580
|
+
with_scope_level(:member) do
|
581
|
+
scope(resource.options) do
|
582
|
+
get :show if resource.actions.include?(:show)
|
583
|
+
post :create if resource.actions.include?(:create)
|
584
|
+
put :update if resource.actions.include?(:update)
|
585
|
+
delete :destroy if resource.actions.include?(:destroy)
|
586
|
+
get :new, :as => resource.name if resource.actions.include?(:new)
|
587
|
+
get :edit, :as => resource.name if resource.actions.include?(:edit)
|
588
|
+
end
|
567
589
|
end
|
568
590
|
end
|
569
591
|
end
|
@@ -573,6 +595,7 @@ module ActionDispatch
|
|
573
595
|
|
574
596
|
def resources(*resources, &block)
|
575
597
|
options = resources.extract_options!
|
598
|
+
options = (@scope[:options] || {}).merge(options)
|
576
599
|
|
577
600
|
if apply_common_behavior_for(:resources, resources, options, &block)
|
578
601
|
return self
|
@@ -621,29 +644,49 @@ module ActionDispatch
|
|
621
644
|
end
|
622
645
|
|
623
646
|
def member
|
624
|
-
unless
|
625
|
-
raise ArgumentError, "can't use member outside
|
647
|
+
unless resource_scope?
|
648
|
+
raise ArgumentError, "can't use member outside resource(s) scope"
|
626
649
|
end
|
627
650
|
|
628
651
|
with_scope_level(:member) do
|
629
|
-
scope(
|
652
|
+
scope(parent_resource.member_prefix, :name_prefix => parent_resource.member_name, :as => "") do
|
653
|
+
yield
|
654
|
+
end
|
655
|
+
end
|
656
|
+
end
|
657
|
+
|
658
|
+
def new
|
659
|
+
unless resource_scope?
|
660
|
+
raise ArgumentError, "can't use new outside resource(s) scope"
|
661
|
+
end
|
662
|
+
|
663
|
+
with_scope_level(:new) do
|
664
|
+
scope(new_scope_prefix, :name_prefix => parent_resource.member_name, :as => "") do
|
630
665
|
yield
|
631
666
|
end
|
632
667
|
end
|
633
668
|
end
|
634
669
|
|
635
670
|
def nested
|
636
|
-
unless
|
637
|
-
raise ArgumentError, "can't use nested outside
|
671
|
+
unless resource_scope?
|
672
|
+
raise ArgumentError, "can't use nested outside resource(s) scope"
|
638
673
|
end
|
639
674
|
|
640
675
|
with_scope_level(:nested) do
|
641
|
-
scope(parent_resource.
|
676
|
+
scope(parent_resource.nested_prefix, parent_resource.nested_options) do
|
642
677
|
yield
|
643
678
|
end
|
644
679
|
end
|
645
680
|
end
|
646
681
|
|
682
|
+
def namespace(path)
|
683
|
+
if resource_scope?
|
684
|
+
nested { super }
|
685
|
+
else
|
686
|
+
super
|
687
|
+
end
|
688
|
+
end
|
689
|
+
|
647
690
|
def match(*args)
|
648
691
|
options = args.extract_options!
|
649
692
|
|
@@ -670,7 +713,7 @@ module ActionDispatch
|
|
670
713
|
@scope[:path] = old_path
|
671
714
|
end
|
672
715
|
else
|
673
|
-
with_exclusive_name_prefix(action) do
|
716
|
+
with_exclusive_name_prefix(action_name_prefix(action, options)) do
|
674
717
|
return match("#{action_path(action, path_names)}(.:format)", options.reverse_merge(:to => action))
|
675
718
|
end
|
676
719
|
end
|
@@ -683,15 +726,26 @@ module ActionDispatch
|
|
683
726
|
return collection { match(*args) }
|
684
727
|
when :member
|
685
728
|
return member { match(*args) }
|
729
|
+
when :new
|
730
|
+
return new { match(*args) }
|
686
731
|
end
|
687
732
|
|
688
|
-
if @scope[:scope_level] == :
|
689
|
-
|
733
|
+
if @scope[:scope_level] == :resource
|
734
|
+
return member { match(*args) }
|
735
|
+
end
|
736
|
+
|
737
|
+
if resource_scope?
|
738
|
+
raise ArgumentError, "can't define route directly in resource(s) scope"
|
690
739
|
end
|
691
740
|
|
692
741
|
super
|
693
742
|
end
|
694
743
|
|
744
|
+
def root(options={})
|
745
|
+
options[:on] ||= :collection if @scope[:scope_level] == :resources
|
746
|
+
super(options)
|
747
|
+
end
|
748
|
+
|
695
749
|
protected
|
696
750
|
def parent_resource #:nodoc:
|
697
751
|
@scope[:scope_level_resource]
|
@@ -703,6 +757,10 @@ module ActionDispatch
|
|
703
757
|
path_names[name.to_sym] || name.to_s
|
704
758
|
end
|
705
759
|
|
760
|
+
def action_name_prefix(action, options = {})
|
761
|
+
(options[:on] == :new || @scope[:scope_level] == :new) ? "#{action}_new" : action
|
762
|
+
end
|
763
|
+
|
706
764
|
def apply_common_behavior_for(method, resources, options, &block)
|
707
765
|
if resources.length > 1
|
708
766
|
resources.each { |r| send(method, r, options, &block) }
|
@@ -716,7 +774,7 @@ module ActionDispatch
|
|
716
774
|
return true
|
717
775
|
end
|
718
776
|
|
719
|
-
if
|
777
|
+
if resource_scope?
|
720
778
|
nested do
|
721
779
|
send(method, resources.pop, options, &block)
|
722
780
|
end
|
@@ -726,6 +784,14 @@ module ActionDispatch
|
|
726
784
|
false
|
727
785
|
end
|
728
786
|
|
787
|
+
def new_scope_prefix
|
788
|
+
@scope[:path_names][:new] || 'new'
|
789
|
+
end
|
790
|
+
|
791
|
+
def resource_scope?
|
792
|
+
[:resource, :resources].include?(@scope[:scope_level])
|
793
|
+
end
|
794
|
+
|
729
795
|
def with_exclusive_name_prefix(prefix)
|
730
796
|
begin
|
731
797
|
old_name_prefix = @scope[:name_prefix]
|