actionpack 2.1.2 → 2.2.2
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 +223 -7
- data/README +6 -12
- data/Rakefile +11 -11
- data/lib/action_controller.rb +9 -9
- data/lib/action_controller/assertions/response_assertions.rb +29 -78
- data/lib/action_controller/assertions/routing_assertions.rb +33 -33
- data/lib/action_controller/assertions/selector_assertions.rb +9 -5
- data/lib/action_controller/base.rb +227 -161
- data/lib/action_controller/benchmarking.rb +37 -24
- data/lib/action_controller/caching/actions.rb +53 -21
- data/lib/action_controller/caching/fragments.rb +10 -36
- data/lib/action_controller/caching/sweeping.rb +3 -3
- data/lib/action_controller/cgi_ext/session.rb +2 -22
- data/lib/action_controller/cgi_process.rb +8 -46
- data/lib/action_controller/components.rb +4 -1
- data/lib/action_controller/cookies.rb +10 -0
- data/lib/action_controller/dispatcher.rb +49 -15
- data/lib/action_controller/filters.rb +48 -10
- data/lib/action_controller/headers.rb +16 -14
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +57 -60
- data/lib/action_controller/layout.rb +27 -53
- data/lib/action_controller/mime_responds.rb +5 -1
- data/lib/action_controller/mime_type.rb +64 -42
- data/lib/action_controller/mime_types.rb +2 -1
- data/lib/action_controller/performance_test.rb +16 -0
- data/lib/action_controller/polymorphic_routes.rb +16 -9
- data/lib/action_controller/rack_process.rb +303 -0
- data/lib/action_controller/request.rb +205 -97
- data/lib/action_controller/request_forgery_protection.rb +2 -2
- data/lib/action_controller/request_profiler.rb +0 -0
- data/lib/action_controller/rescue.rb +20 -115
- data/lib/action_controller/resources.rb +186 -83
- data/lib/action_controller/response.rb +140 -26
- data/lib/action_controller/routing.rb +28 -30
- data/lib/action_controller/routing/builder.rb +45 -54
- data/lib/action_controller/routing/optimisations.rb +31 -21
- data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
- data/lib/action_controller/routing/route.rb +162 -147
- data/lib/action_controller/routing/route_set.rb +8 -7
- data/lib/action_controller/routing/routing_ext.rb +4 -1
- data/lib/action_controller/routing/segments.rb +50 -21
- data/lib/action_controller/session/cookie_store.rb +3 -2
- data/lib/action_controller/session/drb_server.rb +7 -7
- data/lib/action_controller/session_management.rb +6 -2
- data/lib/action_controller/streaming.rb +15 -8
- data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
- data/lib/action_controller/templates/rescues/template_error.erb +2 -2
- data/lib/action_controller/test_case.rb +66 -2
- data/lib/action_controller/test_process.rb +71 -66
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +90 -13
- data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
- data/lib/action_controller/verification.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +19 -11
- data/lib/action_view/base.rb +184 -150
- data/lib/action_view/helpers.rb +38 -0
- data/lib/action_view/helpers/active_record_helper.rb +56 -27
- data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
- data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
- data/lib/action_view/helpers/benchmark_helper.rb +3 -3
- data/lib/action_view/helpers/cache_helper.rb +1 -2
- data/lib/action_view/helpers/capture_helper.rb +19 -44
- data/lib/action_view/helpers/date_helper.rb +486 -296
- data/lib/action_view/helpers/debug_helper.rb +20 -13
- data/lib/action_view/helpers/form_helper.rb +71 -30
- data/lib/action_view/helpers/form_options_helper.rb +15 -85
- data/lib/action_view/helpers/form_tag_helper.rb +61 -38
- data/lib/action_view/helpers/javascript_helper.rb +80 -89
- data/lib/action_view/helpers/number_helper.rb +179 -74
- data/lib/action_view/helpers/prototype_helper.rb +216 -201
- data/lib/action_view/helpers/record_tag_helper.rb +4 -5
- data/lib/action_view/helpers/sanitize_helper.rb +65 -33
- data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +39 -22
- data/lib/action_view/helpers/text_helper.rb +212 -118
- data/lib/action_view/helpers/translation_helper.rb +21 -0
- data/lib/action_view/helpers/url_helper.rb +100 -58
- data/lib/action_view/inline_template.rb +13 -14
- data/lib/action_view/locale/en.yml +91 -0
- data/lib/action_view/partials.rb +100 -55
- data/lib/action_view/paths.rb +125 -0
- data/lib/action_view/renderable.rb +102 -0
- data/lib/action_view/renderable_partial.rb +48 -0
- data/lib/action_view/template.rb +90 -101
- data/lib/action_view/template_error.rb +11 -21
- data/lib/action_view/template_handler.rb +8 -28
- data/lib/action_view/template_handlers.rb +45 -0
- data/lib/action_view/template_handlers/builder.rb +5 -15
- data/lib/action_view/template_handlers/erb.rb +9 -6
- data/lib/action_view/template_handlers/rjs.rb +2 -17
- data/lib/action_view/test_case.rb +7 -4
- data/test/abstract_unit.rb +4 -1
- data/test/active_record_unit.rb +28 -30
- data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
- data/test/controller/action_pack_assertions_test.rb +8 -37
- data/test/controller/addresses_render_test.rb +0 -3
- data/test/controller/assert_select_test.rb +51 -24
- data/test/controller/base_test.rb +4 -4
- data/test/controller/caching_test.rb +136 -66
- data/test/controller/capture_test.rb +1 -21
- data/test/controller/cgi_test.rb +157 -10
- data/test/controller/components_test.rb +41 -25
- data/test/controller/content_type_test.rb +49 -17
- data/test/controller/cookie_test.rb +1 -1
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
- data/test/controller/dispatcher_test.rb +9 -1
- data/test/controller/filter_params_test.rb +2 -2
- data/test/controller/filters_test.rb +13 -13
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/node_test.rb +21 -0
- data/test/controller/html-scanner/sanitizer_test.rb +14 -0
- data/test/controller/integration_test.rb +167 -6
- data/test/controller/layout_test.rb +11 -68
- data/test/controller/logging_test.rb +46 -0
- data/test/controller/mime_responds_test.rb +61 -59
- data/test/controller/mime_type_test.rb +6 -6
- data/test/controller/polymorphic_routes_test.rb +37 -2
- data/test/controller/rack_test.rb +323 -0
- data/test/controller/redirect_test.rb +72 -71
- data/test/controller/render_test.rb +1120 -108
- data/test/controller/request_forgery_protection_test.rb +66 -52
- data/test/controller/request_test.rb +103 -146
- data/test/controller/rescue_test.rb +20 -24
- data/test/controller/resources_test.rb +408 -25
- data/test/controller/routing_test.rb +1774 -1774
- data/test/controller/send_file_test.rb +0 -4
- data/test/controller/session/cookie_store_test.rb +53 -1
- data/test/controller/test_test.rb +15 -37
- data/test/controller/translation_test.rb +26 -0
- data/test/controller/url_rewriter_test.rb +27 -28
- data/test/controller/view_paths_test.rb +48 -47
- data/test/fixtures/_top_level_partial.html.erb +1 -0
- data/test/fixtures/_top_level_partial_only.erb +1 -0
- data/test/fixtures/developers/_developer.erb +1 -0
- data/test/fixtures/fun/games/_game.erb +1 -0
- data/test/fixtures/fun/serious/games/_game.erb +1 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
- data/test/fixtures/layouts/_column.html.erb +2 -0
- data/test/fixtures/projects/_project.erb +1 -0
- data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
- data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
- data/test/fixtures/replies/_reply.erb +1 -0
- data/test/fixtures/test/_counter.html.erb +1 -0
- data/test/fixtures/test/_customer.erb +1 -1
- data/test/fixtures/test/_customer_with_var.erb +1 -0
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
- data/test/fixtures/test/_local_inspector.html.erb +1 -0
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hyphen-ated.erb +1 -0
- data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
- data/test/fixtures/test/nested_layout.erb +3 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
- data/test/fixtures/test/sub_template_raise.html.erb +1 -0
- data/test/fixtures/test/template.erb +1 -0
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
- data/test/template/active_record_helper_i18n_test.rb +46 -0
- data/test/template/active_record_helper_test.rb +24 -24
- data/test/template/asset_tag_helper_test.rb +161 -29
- data/test/template/atom_feed_helper_test.rb +114 -5
- data/test/template/compiled_templates_test.rb +59 -0
- data/test/template/date_helper_i18n_test.rb +113 -0
- data/test/template/date_helper_test.rb +403 -109
- data/test/template/form_helper_test.rb +213 -154
- data/test/template/form_options_helper_test.rb +249 -897
- data/test/template/form_tag_helper_test.rb +80 -32
- data/test/template/javascript_helper_test.rb +17 -18
- data/test/template/number_helper_i18n_test.rb +54 -0
- data/test/template/number_helper_test.rb +43 -13
- data/test/template/prototype_helper_test.rb +101 -84
- data/test/template/record_tag_helper_test.rb +24 -20
- data/test/template/render_test.rb +193 -0
- data/test/template/sanitize_helper_test.rb +3 -3
- data/test/template/tag_helper_test.rb +34 -14
- data/test/template/text_helper_test.rb +83 -9
- data/test/template/translation_helper_test.rb +28 -0
- data/test/template/url_helper_test.rb +55 -18
- metadata +57 -18
- data/lib/action_view/helpers/javascripts/controls.js +0 -963
- data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
- data/lib/action_view/helpers/javascripts/effects.js +0 -1120
- data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
- data/lib/action_view/partial_template.rb +0 -70
- data/lib/action_view/template_finder.rb +0 -177
- data/lib/action_view/template_handlers/compilable.rb +0 -128
- data/test/controller/custom_handler_test.rb +0 -45
- data/test/controller/new_render_test.rb +0 -945
- data/test/fixtures/test/block_content_for.erb +0 -2
- data/test/fixtures/test/erb_content_for.erb +0 -2
- data/test/template/deprecated_erb_variable_test.rb +0 -9
- data/test/template/template_finder_test.rb +0 -73
- data/test/template/template_object_test.rb +0 -95
@@ -38,6 +38,7 @@ module ActionController #:nodoc:
|
|
38
38
|
def self.included(base) #:nodoc:
|
39
39
|
base.class_eval do
|
40
40
|
include InstanceMethods
|
41
|
+
include ActiveSupport::Deprecation
|
41
42
|
extend ClassMethods
|
42
43
|
helper HelperMethods
|
43
44
|
|
@@ -64,7 +65,7 @@ module ActionController #:nodoc:
|
|
64
65
|
|
65
66
|
module HelperMethods
|
66
67
|
def render_component(options)
|
67
|
-
@controller.
|
68
|
+
@controller.__send__(:render_component_as_string, options)
|
68
69
|
end
|
69
70
|
end
|
70
71
|
|
@@ -82,6 +83,7 @@ module ActionController #:nodoc:
|
|
82
83
|
render_for_text(component_response(options, true).body, response.headers["Status"])
|
83
84
|
end
|
84
85
|
end
|
86
|
+
deprecate :render_component => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
|
85
87
|
|
86
88
|
# Returns the component response as a string
|
87
89
|
def render_component_as_string(options) #:doc:
|
@@ -95,6 +97,7 @@ module ActionController #:nodoc:
|
|
95
97
|
end
|
96
98
|
end
|
97
99
|
end
|
100
|
+
deprecate :render_component_as_string => "Please install render_component plugin from http://github.com/rails/render_component/tree/master"
|
98
101
|
|
99
102
|
def flash_with_components(refresh = false) #:nodoc:
|
100
103
|
if !defined?(@_flash) || refresh
|
@@ -22,6 +22,16 @@ module ActionController #:nodoc:
|
|
22
22
|
#
|
23
23
|
# cookies.delete :user_name
|
24
24
|
#
|
25
|
+
# Please note that if you specify a :domain when setting a cookie, you must also specify the domain when deleting the cookie:
|
26
|
+
#
|
27
|
+
# cookies[:key] = {
|
28
|
+
# :value => 'a yummy cookie',
|
29
|
+
# :expires => 1.year.from_now,
|
30
|
+
# :domain => 'domain.com'
|
31
|
+
# }
|
32
|
+
#
|
33
|
+
# cookies.delete(:key, :domain => 'domain.com')
|
34
|
+
#
|
25
35
|
# The option symbols for setting cookies are:
|
26
36
|
#
|
27
37
|
# * <tt>:value</tt> - The cookie's value or list of values (as an array).
|
@@ -22,11 +22,15 @@ module ActionController
|
|
22
22
|
end
|
23
23
|
|
24
24
|
if defined?(ActiveRecord)
|
25
|
-
|
25
|
+
after_dispatch :checkin_connections
|
26
26
|
to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers }
|
27
27
|
end
|
28
28
|
|
29
|
-
after_dispatch :flush_logger if
|
29
|
+
after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush)
|
30
|
+
|
31
|
+
to_prepare do
|
32
|
+
I18n.reload!
|
33
|
+
end
|
30
34
|
end
|
31
35
|
|
32
36
|
# Backward-compatible class method takes CGI-specific args. Deprecated
|
@@ -38,7 +42,7 @@ module ActionController
|
|
38
42
|
# Add a preparation callback. Preparation callbacks are run before every
|
39
43
|
# request in development mode, and before the first request in production
|
40
44
|
# mode.
|
41
|
-
#
|
45
|
+
#
|
42
46
|
# An optional identifier may be supplied for the callback. If provided,
|
43
47
|
# to_prepare may be called again with the same identifier to replace the
|
44
48
|
# existing callback. Passing an identifier is a suggested practice if the
|
@@ -46,7 +50,7 @@ module ActionController
|
|
46
50
|
def to_prepare(identifier = nil, &block)
|
47
51
|
@prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new
|
48
52
|
callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier)
|
49
|
-
@prepare_dispatch_callbacks
|
53
|
+
@prepare_dispatch_callbacks.replace_or_append!(callback)
|
50
54
|
end
|
51
55
|
|
52
56
|
# If the block raises, send status code as a last-ditch response.
|
@@ -96,19 +100,27 @@ module ActionController
|
|
96
100
|
include ActiveSupport::Callbacks
|
97
101
|
define_callbacks :prepare_dispatch, :before_dispatch, :after_dispatch
|
98
102
|
|
99
|
-
def initialize(output, request = nil, response = nil)
|
103
|
+
def initialize(output = $stdout, request = nil, response = nil)
|
100
104
|
@output, @request, @response = output, request, response
|
101
105
|
end
|
102
106
|
|
107
|
+
def dispatch_unlocked
|
108
|
+
begin
|
109
|
+
run_callbacks :before_dispatch
|
110
|
+
handle_request
|
111
|
+
rescue Exception => exception
|
112
|
+
failsafe_rescue exception
|
113
|
+
ensure
|
114
|
+
run_callbacks :after_dispatch, :enumerator => :reverse_each
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
103
118
|
def dispatch
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
failsafe_rescue exception
|
110
|
-
ensure
|
111
|
-
run_callbacks :after_dispatch, :enumerator => :reverse_each
|
119
|
+
if ActionController::Base.allow_concurrency
|
120
|
+
dispatch_unlocked
|
121
|
+
else
|
122
|
+
@@guard.synchronize do
|
123
|
+
dispatch_unlocked
|
112
124
|
end
|
113
125
|
end
|
114
126
|
end
|
@@ -123,12 +135,19 @@ module ActionController
|
|
123
135
|
failsafe_rescue exception
|
124
136
|
end
|
125
137
|
|
138
|
+
def call(env)
|
139
|
+
@request = RackRequest.new(env)
|
140
|
+
@response = RackResponse.new(@request)
|
141
|
+
dispatch
|
142
|
+
end
|
143
|
+
|
126
144
|
def reload_application
|
127
145
|
# Run prepare callbacks before every request in development mode
|
128
146
|
run_callbacks :prepare_dispatch
|
129
147
|
|
130
148
|
Routing::Routes.reload
|
131
|
-
|
149
|
+
ActionController::Base.view_paths.reload!
|
150
|
+
ActionView::Helpers::AssetTagHelper::AssetTag::Cache.clear
|
132
151
|
end
|
133
152
|
|
134
153
|
# Cleanup the application by clearing out loaded classes so they can
|
@@ -140,7 +159,22 @@ module ActionController
|
|
140
159
|
end
|
141
160
|
|
142
161
|
def flush_logger
|
143
|
-
|
162
|
+
Base.logger.flush
|
163
|
+
end
|
164
|
+
|
165
|
+
def mark_as_test_request!
|
166
|
+
@test_request = true
|
167
|
+
self
|
168
|
+
end
|
169
|
+
|
170
|
+
def test_request?
|
171
|
+
@test_request
|
172
|
+
end
|
173
|
+
|
174
|
+
def checkin_connections
|
175
|
+
# Don't return connection (and peform implicit rollback) if this request is a part of integration test
|
176
|
+
return if test_request?
|
177
|
+
ActiveRecord::Base.clear_active_connections!
|
144
178
|
end
|
145
179
|
|
146
180
|
protected
|
@@ -94,7 +94,7 @@ module ActionController #:nodoc:
|
|
94
94
|
map! do |filter|
|
95
95
|
if filters.include?(filter)
|
96
96
|
new_filter = filter.dup
|
97
|
-
new_filter.
|
97
|
+
new_filter.update_options!(options)
|
98
98
|
new_filter
|
99
99
|
else
|
100
100
|
filter
|
@@ -104,16 +104,34 @@ module ActionController #:nodoc:
|
|
104
104
|
end
|
105
105
|
|
106
106
|
class Filter < ActiveSupport::Callbacks::Callback #:nodoc:
|
107
|
+
def initialize(kind, method, options = {})
|
108
|
+
super
|
109
|
+
update_options! options
|
110
|
+
end
|
111
|
+
|
112
|
+
# override these to return true in appropriate subclass
|
107
113
|
def before?
|
108
|
-
|
114
|
+
false
|
109
115
|
end
|
110
116
|
|
111
117
|
def after?
|
112
|
-
|
118
|
+
false
|
113
119
|
end
|
114
120
|
|
115
121
|
def around?
|
116
|
-
|
122
|
+
false
|
123
|
+
end
|
124
|
+
|
125
|
+
# Make sets of strings from :only/:except options
|
126
|
+
def update_options!(other)
|
127
|
+
if other
|
128
|
+
convert_only_and_except_options_to_sets_of_strings(other)
|
129
|
+
if other[:skip]
|
130
|
+
convert_only_and_except_options_to_sets_of_strings(other[:skip])
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
options.update(other)
|
117
135
|
end
|
118
136
|
|
119
137
|
private
|
@@ -127,9 +145,9 @@ module ActionController #:nodoc:
|
|
127
145
|
|
128
146
|
def included_in_action?(controller, options)
|
129
147
|
if options[:only]
|
130
|
-
|
148
|
+
options[:only].include?(controller.action_name)
|
131
149
|
elsif options[:except]
|
132
|
-
!
|
150
|
+
!options[:except].include?(controller.action_name)
|
133
151
|
else
|
134
152
|
true
|
135
153
|
end
|
@@ -138,6 +156,14 @@ module ActionController #:nodoc:
|
|
138
156
|
def should_run_callback?(controller)
|
139
157
|
should_not_skip?(controller) && included_in_action?(controller, options) && super
|
140
158
|
end
|
159
|
+
|
160
|
+
def convert_only_and_except_options_to_sets_of_strings(opts)
|
161
|
+
[:only, :except].each do |key|
|
162
|
+
if values = opts[key]
|
163
|
+
opts[key] = Array(values).map(&:to_s).to_set
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
141
167
|
end
|
142
168
|
|
143
169
|
class AroundFilter < Filter #:nodoc:
|
@@ -145,6 +171,10 @@ module ActionController #:nodoc:
|
|
145
171
|
:around
|
146
172
|
end
|
147
173
|
|
174
|
+
def around?
|
175
|
+
true
|
176
|
+
end
|
177
|
+
|
148
178
|
def call(controller, &block)
|
149
179
|
if should_run_callback?(controller)
|
150
180
|
method = filter_responds_to_before_and_after? ? around_proc : self.method
|
@@ -169,8 +199,8 @@ module ActionController #:nodoc:
|
|
169
199
|
Proc.new do |controller, action|
|
170
200
|
method.before(controller)
|
171
201
|
|
172
|
-
if controller.
|
173
|
-
controller.
|
202
|
+
if controller.__send__(:performed?)
|
203
|
+
controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
|
174
204
|
else
|
175
205
|
begin
|
176
206
|
action.call
|
@@ -187,10 +217,14 @@ module ActionController #:nodoc:
|
|
187
217
|
:before
|
188
218
|
end
|
189
219
|
|
220
|
+
def before?
|
221
|
+
true
|
222
|
+
end
|
223
|
+
|
190
224
|
def call(controller, &block)
|
191
225
|
super
|
192
|
-
if controller.
|
193
|
-
controller.
|
226
|
+
if controller.__send__(:performed?)
|
227
|
+
controller.__send__(:halt_filter_chain, method, :rendered_or_redirected)
|
194
228
|
end
|
195
229
|
end
|
196
230
|
end
|
@@ -199,6 +233,10 @@ module ActionController #:nodoc:
|
|
199
233
|
def type
|
200
234
|
:after
|
201
235
|
end
|
236
|
+
|
237
|
+
def after?
|
238
|
+
true
|
239
|
+
end
|
202
240
|
end
|
203
241
|
|
204
242
|
# Filters enable controllers to run shared pre- and post-processing code for its actions. These filters can be used to do
|
@@ -1,31 +1,33 @@
|
|
1
|
+
require 'active_support/memoizable'
|
2
|
+
|
1
3
|
module ActionController
|
2
4
|
module Http
|
3
5
|
class Headers < ::Hash
|
4
|
-
|
5
|
-
|
6
|
-
|
6
|
+
extend ActiveSupport::Memoizable
|
7
|
+
|
8
|
+
def initialize(*args)
|
9
|
+
if args.size == 1 && args[0].is_a?(Hash)
|
7
10
|
super()
|
8
|
-
update(
|
11
|
+
update(args[0])
|
9
12
|
else
|
10
|
-
super
|
13
|
+
super
|
11
14
|
end
|
12
15
|
end
|
13
|
-
|
16
|
+
|
14
17
|
def [](header_name)
|
15
18
|
if include?(header_name)
|
16
|
-
super
|
19
|
+
super
|
17
20
|
else
|
18
|
-
super(
|
21
|
+
super(env_name(header_name))
|
19
22
|
end
|
20
23
|
end
|
21
|
-
|
22
|
-
|
24
|
+
|
23
25
|
private
|
24
|
-
#
|
25
|
-
|
26
|
-
def normalize_header(header_name)
|
26
|
+
# Converts a HTTP header name to an environment variable name.
|
27
|
+
def env_name(header_name)
|
27
28
|
"HTTP_#{header_name.upcase.gsub(/-/, '_')}"
|
28
29
|
end
|
30
|
+
memoize :env_name
|
29
31
|
end
|
30
32
|
end
|
31
|
-
end
|
33
|
+
end
|
@@ -204,8 +204,8 @@ module ActionController #:nodoc:
|
|
204
204
|
|
205
205
|
begin
|
206
206
|
child.master_helper_module = Module.new
|
207
|
-
child.master_helper_module.
|
208
|
-
child.
|
207
|
+
child.master_helper_module.__send__ :include, master_helper_module
|
208
|
+
child.__send__ :default_helper_module!
|
209
209
|
rescue MissingSourceFile => e
|
210
210
|
raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
|
211
211
|
end
|
@@ -117,7 +117,7 @@ module ActionController
|
|
117
117
|
|
118
118
|
def authentication_request(controller, realm)
|
119
119
|
controller.headers["WWW-Authenticate"] = %(Basic realm="#{realm.gsub(/"/, "")}")
|
120
|
-
controller.
|
120
|
+
controller.__send__ :render, :text => "HTTP Basic: Access denied.\n", :status => :unauthorized
|
121
121
|
end
|
122
122
|
end
|
123
123
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
-
require '
|
2
|
-
require 'uri'
|
3
|
-
|
1
|
+
require 'active_support/test_case'
|
4
2
|
require 'action_controller/dispatcher'
|
5
3
|
require 'action_controller/test_process'
|
6
4
|
|
5
|
+
require 'stringio'
|
6
|
+
require 'uri'
|
7
|
+
|
7
8
|
module ActionController
|
8
9
|
module Integration #:nodoc:
|
9
10
|
# An integration Session instance represents a set of requests and responses
|
@@ -100,7 +101,7 @@ module ActionController
|
|
100
101
|
@https = flag
|
101
102
|
end
|
102
103
|
|
103
|
-
# Return +true+ if the session is
|
104
|
+
# Return +true+ if the session is mimicking a secure HTTPS request.
|
104
105
|
#
|
105
106
|
# if session.https?
|
106
107
|
# ...
|
@@ -164,11 +165,19 @@ module ActionController
|
|
164
165
|
status/100 == 3
|
165
166
|
end
|
166
167
|
|
167
|
-
# Performs a GET request with the given parameters.
|
168
|
-
#
|
169
|
-
#
|
170
|
-
# The
|
171
|
-
#
|
168
|
+
# Performs a GET request with the given parameters.
|
169
|
+
#
|
170
|
+
# - +path+: The URI (as a String) on which you want to perform a GET request.
|
171
|
+
# - +parameters+: The HTTP parameters that you want to pass. This may be +nil+,
|
172
|
+
# a Hash, or a String that is appropriately encoded
|
173
|
+
# (<tt>application/x-www-form-urlencoded</tt> or <tt>multipart/form-data</tt>).
|
174
|
+
# - +headers+: Additional HTTP headers to pass, as a Hash. The keys will
|
175
|
+
# automatically be upcased, with the prefix 'HTTP_' added if needed.
|
176
|
+
#
|
177
|
+
# This method returns an AbstractResponse object, which one can use to inspect
|
178
|
+
# the details of the response. Furthermore, if this method was called from an
|
179
|
+
# ActionController::IntegrationTest object, then that object's <tt>@response</tt>
|
180
|
+
# instance variable will point to the same response object.
|
172
181
|
#
|
173
182
|
# You can also perform POST, PUT, DELETE, and HEAD requests with +post+,
|
174
183
|
# +put+, +delete+, and +head+.
|
@@ -219,21 +228,6 @@ module ActionController
|
|
219
228
|
end
|
220
229
|
|
221
230
|
private
|
222
|
-
class StubCGI < CGI #:nodoc:
|
223
|
-
attr_accessor :stdinput, :stdoutput, :env_table
|
224
|
-
|
225
|
-
def initialize(env, stdinput = nil)
|
226
|
-
self.env_table = env
|
227
|
-
self.stdoutput = StringIO.new
|
228
|
-
|
229
|
-
super
|
230
|
-
|
231
|
-
stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding)
|
232
|
-
stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding)
|
233
|
-
@stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '')
|
234
|
-
end
|
235
|
-
end
|
236
|
-
|
237
231
|
# Tailors the session based on the given URI, setting the HTTPS value
|
238
232
|
# and the hostname.
|
239
233
|
def interpret_uri(path)
|
@@ -281,9 +275,8 @@ module ActionController
|
|
281
275
|
|
282
276
|
ActionController::Base.clear_last_instantiation!
|
283
277
|
|
284
|
-
|
285
|
-
ActionController::Dispatcher.
|
286
|
-
@result = cgi.stdoutput.string
|
278
|
+
env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '')
|
279
|
+
@status, @headers, result_body = ActionController::Dispatcher.new.mark_as_test_request!.call(env)
|
287
280
|
@request_count += 1
|
288
281
|
|
289
282
|
@controller = ActionController::Base.last_instantiation
|
@@ -297,32 +290,34 @@ module ActionController
|
|
297
290
|
|
298
291
|
@html_document = nil
|
299
292
|
|
300
|
-
|
301
|
-
|
302
|
-
rescue MultiPartNeededException
|
303
|
-
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
|
304
|
-
status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
|
305
|
-
return status
|
306
|
-
end
|
293
|
+
# Inject status back in for backwords compatibility with CGI
|
294
|
+
@headers['Status'] = @status
|
307
295
|
|
308
|
-
|
309
|
-
|
310
|
-
def parse_result
|
311
|
-
response_headers, result_body = @result.split(/\r\n\r\n/, 2)
|
296
|
+
@status, @status_message = @status.split(/ /)
|
297
|
+
@status = @status.to_i
|
312
298
|
|
313
|
-
|
314
|
-
|
315
|
-
key
|
316
|
-
@headers[key.downcase] << value
|
299
|
+
cgi_headers = Hash.new { |h,k| h[k] = [] }
|
300
|
+
@headers.each do |key, value|
|
301
|
+
cgi_headers[key.downcase] << value
|
317
302
|
end
|
303
|
+
cgi_headers['set-cookie'] = cgi_headers['set-cookie'].first
|
304
|
+
@headers = cgi_headers
|
318
305
|
|
319
|
-
|
320
|
-
|
306
|
+
@response.headers['cookie'] ||= []
|
307
|
+
(@headers['set-cookie'] || []).each do |cookie|
|
308
|
+
name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2]
|
321
309
|
@cookies[name] = value
|
310
|
+
|
311
|
+
# Fake CGI cookie header
|
312
|
+
# DEPRECATE: Use response.headers["Set-Cookie"] instead
|
313
|
+
@response.headers['cookie'] << CGI::Cookie::new("name" => name, "value" => value)
|
322
314
|
end
|
323
315
|
|
324
|
-
|
325
|
-
|
316
|
+
return status
|
317
|
+
rescue MultiPartNeededException
|
318
|
+
boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1"
|
319
|
+
status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"}))
|
320
|
+
return status
|
326
321
|
end
|
327
322
|
|
328
323
|
# Encode the cookies hash in a format suitable for passing to a
|
@@ -335,13 +330,15 @@ module ActionController
|
|
335
330
|
|
336
331
|
# Get a temporary URL writer object
|
337
332
|
def generic_url_rewriter
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
|
342
|
-
|
343
|
-
|
344
|
-
|
333
|
+
env = {
|
334
|
+
'REQUEST_METHOD' => "GET",
|
335
|
+
'QUERY_STRING' => "",
|
336
|
+
"REQUEST_URI" => "/",
|
337
|
+
"HTTP_HOST" => host,
|
338
|
+
"SERVER_PORT" => https? ? "443" : "80",
|
339
|
+
"HTTPS" => https? ? "on" : "off"
|
340
|
+
}
|
341
|
+
ActionController::UrlRewriter.new(ActionController::RackRequest.new(env), {})
|
345
342
|
end
|
346
343
|
|
347
344
|
def name_with_prefix(prefix, name)
|
@@ -442,12 +439,12 @@ EOF
|
|
442
439
|
end
|
443
440
|
|
444
441
|
%w(get post put head delete cookies assigns
|
445
|
-
xml_http_request get_via_redirect post_via_redirect).each do |method|
|
442
|
+
xml_http_request xhr get_via_redirect post_via_redirect).each do |method|
|
446
443
|
define_method(method) do |*args|
|
447
444
|
reset! unless @integration_session
|
448
445
|
# reset the html_document variable, but only for new get/post calls
|
449
446
|
@html_document = nil unless %w(cookies assigns).include?(method)
|
450
|
-
returning @integration_session.
|
447
|
+
returning @integration_session.__send__(method, *args) do
|
451
448
|
copy_session_variables!
|
452
449
|
end
|
453
450
|
end
|
@@ -472,12 +469,12 @@ EOF
|
|
472
469
|
self.class.fixture_table_names.each do |table_name|
|
473
470
|
name = table_name.tr(".", "_")
|
474
471
|
next unless respond_to?(name)
|
475
|
-
extras.
|
472
|
+
extras.__send__(:define_method, name) { |*args| delegate.send(name, *args) }
|
476
473
|
end
|
477
474
|
end
|
478
475
|
|
479
476
|
# delegate add_assertion to the test case
|
480
|
-
extras.
|
477
|
+
extras.__send__(:define_method, :add_assertion) { test_result.add_assertion }
|
481
478
|
session.extend(extras)
|
482
479
|
session.delegate = self
|
483
480
|
session.test_result = @_result
|
@@ -491,14 +488,14 @@ EOF
|
|
491
488
|
def copy_session_variables! #:nodoc:
|
492
489
|
return unless @integration_session
|
493
490
|
%w(controller response request).each do |var|
|
494
|
-
instance_variable_set("@#{var}", @integration_session.
|
491
|
+
instance_variable_set("@#{var}", @integration_session.__send__(var))
|
495
492
|
end
|
496
493
|
end
|
497
494
|
|
498
495
|
# Delegate unhandled messages to the current session instance.
|
499
496
|
def method_missing(sym, *args, &block)
|
500
497
|
reset! unless @integration_session
|
501
|
-
returning @integration_session.
|
498
|
+
returning @integration_session.__send__(sym, *args, &block) do
|
502
499
|
copy_session_variables!
|
503
500
|
end
|
504
501
|
end
|
@@ -580,7 +577,7 @@ EOF
|
|
580
577
|
# end
|
581
578
|
# end
|
582
579
|
# end
|
583
|
-
class IntegrationTest <
|
580
|
+
class IntegrationTest < ActiveSupport::TestCase
|
584
581
|
include Integration::Runner
|
585
582
|
|
586
583
|
# Work around a bug in test/unit caused by the default test being named
|