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
@@ -1,6 +1,6 @@
|
|
1
1
|
module ActionController
|
2
2
|
module Routing
|
3
|
-
class RouteSet #:nodoc:
|
3
|
+
class RouteSet #:nodoc:
|
4
4
|
# Mapper instances are used to build routes. The object passed to the draw
|
5
5
|
# block in config/routes.rb is a Mapper instance.
|
6
6
|
#
|
@@ -115,7 +115,7 @@ module ActionController
|
|
115
115
|
def install(destinations = [ActionController::Base, ActionView::Base], regenerate = false)
|
116
116
|
reset! if regenerate
|
117
117
|
Array(destinations).each do |dest|
|
118
|
-
dest.
|
118
|
+
dest.__send__(:include, @module)
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
@@ -168,6 +168,7 @@ module ActionController
|
|
168
168
|
#
|
169
169
|
@module.module_eval <<-end_eval # We use module_eval to avoid leaks
|
170
170
|
def #{selector}(*args)
|
171
|
+
|
171
172
|
#{generate_optimisation_block(route, kind)}
|
172
173
|
|
173
174
|
opts = if args.empty? || Hash === args.first
|
@@ -194,6 +195,7 @@ module ActionController
|
|
194
195
|
def initialize
|
195
196
|
self.routes = []
|
196
197
|
self.named_routes = NamedRouteCollection.new
|
198
|
+
|
197
199
|
clear_recognize_optimized!
|
198
200
|
end
|
199
201
|
|
@@ -214,7 +216,7 @@ module ActionController
|
|
214
216
|
named_routes.clear
|
215
217
|
@combined_regexp = nil
|
216
218
|
@routes_by_controller = nil
|
217
|
-
# This will force routing/
|
219
|
+
# This will force routing/recognition_optimization.rb
|
218
220
|
# to refresh optimisations.
|
219
221
|
clear_recognize_optimized!
|
220
222
|
end
|
@@ -232,7 +234,6 @@ module ActionController
|
|
232
234
|
Routing.use_controllers! nil # Clear the controller cache so we may discover new ones
|
233
235
|
clear!
|
234
236
|
load_routes!
|
235
|
-
install_helpers
|
236
237
|
end
|
237
238
|
|
238
239
|
# reload! will always force a reload whereas load checks the timestamp first
|
@@ -353,7 +354,7 @@ module ActionController
|
|
353
354
|
if generate_all
|
354
355
|
# Used by caching to expire all paths for a resource
|
355
356
|
return routes.collect do |route|
|
356
|
-
route.
|
357
|
+
route.__send__(method, options, merged, expire_on)
|
357
358
|
end.compact
|
358
359
|
end
|
359
360
|
|
@@ -361,7 +362,7 @@ module ActionController
|
|
361
362
|
routes = routes_by_controller[controller][action][options.keys.sort_by { |x| x.object_id }]
|
362
363
|
|
363
364
|
routes.each do |route|
|
364
|
-
results = route.
|
365
|
+
results = route.__send__(method, options, merged, expire_on)
|
365
366
|
return results if results && (!results.is_a?(Array) || results.first)
|
366
367
|
end
|
367
368
|
end
|
@@ -433,4 +434,4 @@ module ActionController
|
|
433
434
|
end
|
434
435
|
end
|
435
436
|
end
|
436
|
-
end
|
437
|
+
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
class Object
|
3
2
|
def to_param
|
4
3
|
to_s
|
@@ -28,6 +27,10 @@ class Regexp #:nodoc:
|
|
28
27
|
Regexp.new("|#{source}").match('').captures.length
|
29
28
|
end
|
30
29
|
|
30
|
+
def multiline?
|
31
|
+
options & MULTILINE == MULTILINE
|
32
|
+
end
|
33
|
+
|
31
34
|
class << self
|
32
35
|
def optionalize(pattern)
|
33
36
|
case unoptionalize(pattern)
|
@@ -2,13 +2,19 @@ module ActionController
|
|
2
2
|
module Routing
|
3
3
|
class Segment #:nodoc:
|
4
4
|
RESERVED_PCHAR = ':@&=+$,;'
|
5
|
-
|
5
|
+
SAFE_PCHAR = "#{URI::REGEXP::PATTERN::UNRESERVED}#{RESERVED_PCHAR}"
|
6
|
+
UNSAFE_PCHAR = Regexp.new("[^#{SAFE_PCHAR}]", false, 'N').freeze
|
6
7
|
|
8
|
+
# TODO: Convert :is_optional accessor to read only
|
7
9
|
attr_accessor :is_optional
|
8
10
|
alias_method :optional?, :is_optional
|
9
11
|
|
10
12
|
def initialize
|
11
|
-
|
13
|
+
@is_optional = false
|
14
|
+
end
|
15
|
+
|
16
|
+
def number_of_captures
|
17
|
+
Regexp.new(regexp_chunk).number_of_captures
|
12
18
|
end
|
13
19
|
|
14
20
|
def extraction_code
|
@@ -63,12 +69,14 @@ module ActionController
|
|
63
69
|
end
|
64
70
|
|
65
71
|
class StaticSegment < Segment #:nodoc:
|
66
|
-
|
72
|
+
attr_reader :value, :raw
|
67
73
|
alias_method :raw?, :raw
|
68
74
|
|
69
|
-
def initialize(value = nil)
|
75
|
+
def initialize(value = nil, options = {})
|
70
76
|
super()
|
71
|
-
|
77
|
+
@value = value
|
78
|
+
@raw = options[:raw] if options.key?(:raw)
|
79
|
+
@is_optional = options[:optional] if options.key?(:optional)
|
72
80
|
end
|
73
81
|
|
74
82
|
def interpolation_chunk
|
@@ -80,6 +88,10 @@ module ActionController
|
|
80
88
|
optional? ? Regexp.optionalize(chunk) : chunk
|
81
89
|
end
|
82
90
|
|
91
|
+
def number_of_captures
|
92
|
+
0
|
93
|
+
end
|
94
|
+
|
83
95
|
def build_pattern(pattern)
|
84
96
|
escaped = Regexp.escape(value)
|
85
97
|
if optional? && ! pattern.empty?
|
@@ -97,10 +109,8 @@ module ActionController
|
|
97
109
|
end
|
98
110
|
|
99
111
|
class DividerSegment < StaticSegment #:nodoc:
|
100
|
-
def initialize(value = nil)
|
101
|
-
super(value)
|
102
|
-
self.raw = true
|
103
|
-
self.is_optional = true
|
112
|
+
def initialize(value = nil, options = {})
|
113
|
+
super(value, {:raw => true, :optional => true}.merge(options))
|
104
114
|
end
|
105
115
|
|
106
116
|
def optionality_implied?
|
@@ -109,13 +119,17 @@ module ActionController
|
|
109
119
|
end
|
110
120
|
|
111
121
|
class DynamicSegment < Segment #:nodoc:
|
112
|
-
|
122
|
+
attr_reader :key
|
123
|
+
|
124
|
+
# TODO: Convert these accessors to read only
|
125
|
+
attr_accessor :default, :regexp
|
113
126
|
|
114
127
|
def initialize(key = nil, options = {})
|
115
128
|
super()
|
116
|
-
|
117
|
-
|
118
|
-
|
129
|
+
@key = key
|
130
|
+
@default = options[:default] if options.key?(:default)
|
131
|
+
@regexp = options[:regexp] if options.key?(:regexp)
|
132
|
+
@is_optional = true if options[:optional] || options.key?(:default)
|
119
133
|
end
|
120
134
|
|
121
135
|
def to_s
|
@@ -130,6 +144,7 @@ module ActionController
|
|
130
144
|
def extract_value
|
131
145
|
"#{local_name} = hash[:#{key}] && hash[:#{key}].to_param #{"|| #{default.inspect}" if default}"
|
132
146
|
end
|
147
|
+
|
133
148
|
def value_check
|
134
149
|
if default # Then we know it won't be nil
|
135
150
|
"#{value_regexp.inspect} =~ #{local_name}" if regexp
|
@@ -141,6 +156,7 @@ module ActionController
|
|
141
156
|
"#{local_name} #{"&& #{value_regexp.inspect} =~ #{local_name}" if regexp}"
|
142
157
|
end
|
143
158
|
end
|
159
|
+
|
144
160
|
def expiry_statement
|
145
161
|
"expired, hash = true, options if !expired && expire_on[:#{key}]"
|
146
162
|
end
|
@@ -152,7 +168,7 @@ module ActionController
|
|
152
168
|
s << "\n#{expiry_statement}"
|
153
169
|
end
|
154
170
|
|
155
|
-
def interpolation_chunk(value_code =
|
171
|
+
def interpolation_chunk(value_code = local_name)
|
156
172
|
"\#{URI.escape(#{value_code}.to_s, ActionController::Routing::Segment::UNSAFE_PCHAR)}"
|
157
173
|
end
|
158
174
|
|
@@ -175,7 +191,7 @@ module ActionController
|
|
175
191
|
end
|
176
192
|
|
177
193
|
def regexp_chunk
|
178
|
-
if regexp
|
194
|
+
if regexp
|
179
195
|
if regexp_has_modifiers?
|
180
196
|
"(#{regexp.to_s})"
|
181
197
|
else
|
@@ -186,10 +202,16 @@ module ActionController
|
|
186
202
|
end
|
187
203
|
end
|
188
204
|
|
205
|
+
def number_of_captures
|
206
|
+
if regexp
|
207
|
+
regexp.number_of_captures + 1
|
208
|
+
else
|
209
|
+
1
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
189
213
|
def build_pattern(pattern)
|
190
|
-
|
191
|
-
chunk = "(#{chunk})" if Regexp.new(chunk).number_of_captures == 0
|
192
|
-
pattern = "#{chunk}#{pattern}"
|
214
|
+
pattern = "#{regexp_chunk}#{pattern}"
|
193
215
|
optional? ? Regexp.optionalize(pattern) : pattern
|
194
216
|
end
|
195
217
|
|
@@ -214,7 +236,6 @@ module ActionController
|
|
214
236
|
def regexp_has_modifiers?
|
215
237
|
regexp.options & (Regexp::IGNORECASE | Regexp::EXTENDED) != 0
|
216
238
|
end
|
217
|
-
|
218
239
|
end
|
219
240
|
|
220
241
|
class ControllerSegment < DynamicSegment #:nodoc:
|
@@ -223,8 +244,12 @@ module ActionController
|
|
223
244
|
"(?i-:(#{(regexp || Regexp.union(*possible_names)).source}))"
|
224
245
|
end
|
225
246
|
|
247
|
+
def number_of_captures
|
248
|
+
1
|
249
|
+
end
|
250
|
+
|
226
251
|
# Don't URI.escape the controller name since it may contain slashes.
|
227
|
-
def interpolation_chunk(value_code =
|
252
|
+
def interpolation_chunk(value_code = local_name)
|
228
253
|
"\#{#{value_code}.to_s}"
|
229
254
|
end
|
230
255
|
|
@@ -244,7 +269,7 @@ module ActionController
|
|
244
269
|
end
|
245
270
|
|
246
271
|
class PathSegment < DynamicSegment #:nodoc:
|
247
|
-
def interpolation_chunk(value_code =
|
272
|
+
def interpolation_chunk(value_code = local_name)
|
248
273
|
"\#{#{value_code}}"
|
249
274
|
end
|
250
275
|
|
@@ -268,6 +293,10 @@ module ActionController
|
|
268
293
|
regexp || "(.*)"
|
269
294
|
end
|
270
295
|
|
296
|
+
def number_of_captures
|
297
|
+
regexp ? regexp.number_of_captures : 1
|
298
|
+
end
|
299
|
+
|
271
300
|
def optionality_implied?
|
272
301
|
true
|
273
302
|
end
|
@@ -70,7 +70,8 @@ class CGI::Session::CookieStore
|
|
70
70
|
'path' => options['session_path'],
|
71
71
|
'domain' => options['session_domain'],
|
72
72
|
'expires' => options['session_expires'],
|
73
|
-
'secure' => options['session_secure']
|
73
|
+
'secure' => options['session_secure'],
|
74
|
+
'http_only' => options['session_http_only']
|
74
75
|
}
|
75
76
|
|
76
77
|
# Set no_hidden and no_cookies since the session id is unused and we
|
@@ -129,7 +130,7 @@ class CGI::Session::CookieStore
|
|
129
130
|
private
|
130
131
|
# Marshal a session hash into safe cookie data. Include an integrity hash.
|
131
132
|
def marshal(session)
|
132
|
-
data = ActiveSupport::Base64.
|
133
|
+
data = ActiveSupport::Base64.encode64s(Marshal.dump(session))
|
133
134
|
"#{data}--#{generate_digest(data)}"
|
134
135
|
end
|
135
136
|
|
@@ -1,8 +1,8 @@
|
|
1
|
-
#!/usr/
|
2
|
-
|
3
|
-
# This is a really simple session storage daemon, basically just a hash,
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# This is a really simple session storage daemon, basically just a hash,
|
4
4
|
# which is enabled for DRb access.
|
5
|
-
|
5
|
+
|
6
6
|
require 'drb'
|
7
7
|
|
8
8
|
session_hash = Hash.new
|
@@ -14,13 +14,13 @@ class <<session_hash
|
|
14
14
|
super(key, value)
|
15
15
|
end
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
def [](key)
|
19
19
|
@mutex.synchronize do
|
20
20
|
super(key)
|
21
21
|
end
|
22
22
|
end
|
23
|
-
|
23
|
+
|
24
24
|
def delete(key)
|
25
25
|
@mutex.synchronize do
|
26
26
|
super(key)
|
@@ -29,4 +29,4 @@ class <<session_hash
|
|
29
29
|
end
|
30
30
|
|
31
31
|
DRb.start_service('druby://127.0.0.1:9192', session_hash)
|
32
|
-
DRb.thread.join
|
32
|
+
DRb.thread.join
|
@@ -60,6 +60,10 @@ module ActionController #:nodoc:
|
|
60
60
|
# # the session will only work over HTTPS, but only for the foo action
|
61
61
|
# session :only => :foo, :session_secure => true
|
62
62
|
#
|
63
|
+
# # the session by default uses HttpOnly sessions for security reasons.
|
64
|
+
# # this can be switched off.
|
65
|
+
# session :only => :foo, :session_http_only => false
|
66
|
+
#
|
63
67
|
# # the session will only be disabled for 'foo', and only if it is
|
64
68
|
# # requested as a web service
|
65
69
|
# session :off, :only => :foo,
|
@@ -86,14 +90,14 @@ module ActionController #:nodoc:
|
|
86
90
|
raise ArgumentError, "only one of either :only or :except are allowed"
|
87
91
|
end
|
88
92
|
|
89
|
-
write_inheritable_array(
|
93
|
+
write_inheritable_array(:session_options, [options])
|
90
94
|
end
|
91
95
|
|
92
96
|
# So we can declare session options in the Rails initializer.
|
93
97
|
alias_method :session=, :session
|
94
98
|
|
95
99
|
def cached_session_options #:nodoc:
|
96
|
-
@session_options ||= read_inheritable_attribute(
|
100
|
+
@session_options ||= read_inheritable_attribute(:session_options) || []
|
97
101
|
end
|
98
102
|
|
99
103
|
def session_options_for(request, action) #:nodoc:
|
@@ -12,19 +12,21 @@ module ActionController #:nodoc:
|
|
12
12
|
X_SENDFILE_HEADER = 'X-Sendfile'.freeze
|
13
13
|
|
14
14
|
protected
|
15
|
-
# Sends the file by streaming it 4096 bytes at a time. This way the
|
16
|
-
# whole file doesn't need to be read into memory at once.
|
17
|
-
#
|
15
|
+
# Sends the file, by default streaming it 4096 bytes at a time. This way the
|
16
|
+
# whole file doesn't need to be read into memory at once. This makes it
|
17
|
+
# feasible to send even large files. You can optionally turn off streaming
|
18
|
+
# and send the whole file at once.
|
18
19
|
#
|
19
|
-
# Be careful to sanitize the path parameter if it coming from a web
|
20
|
+
# Be careful to sanitize the path parameter if it is coming from a web
|
20
21
|
# page. <tt>send_file(params[:path])</tt> allows a malicious user to
|
21
22
|
# download any file on your server.
|
22
23
|
#
|
23
24
|
# Options:
|
24
25
|
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
25
26
|
# Defaults to <tt>File.basename(path)</tt>.
|
26
|
-
# * <tt>:type</tt> - specifies an HTTP content type.
|
27
|
-
#
|
27
|
+
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
|
28
|
+
# * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
|
29
|
+
# is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
|
28
30
|
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
29
31
|
# Valid values are 'inline' and 'attachment' (default).
|
30
32
|
# * <tt>:stream</tt> - whether to send the file to the user agent as it is read (+true+)
|
@@ -35,6 +37,12 @@ module ActionController #:nodoc:
|
|
35
37
|
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
|
36
38
|
# the URL, which is necessary for i18n filenames on certain browsers
|
37
39
|
# (setting <tt>:filename</tt> overrides this option).
|
40
|
+
# * <tt>:x_sendfile</tt> - uses X-Sendfile to send the file when set to +true+. This is currently
|
41
|
+
# only available with Lighttpd/Apache2 and specific modules installed and activated. Since this
|
42
|
+
# uses the web server to send the file, this may lower memory consumption on your server and
|
43
|
+
# it will not block your application for further requests.
|
44
|
+
# See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and
|
45
|
+
# http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+.
|
38
46
|
#
|
39
47
|
# The default Content-Type and Content-Disposition headers are
|
40
48
|
# set to download arbitrary binary files in as many browsers as
|
@@ -99,8 +107,7 @@ module ActionController #:nodoc:
|
|
99
107
|
#
|
100
108
|
# Options:
|
101
109
|
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
102
|
-
# * <tt>:type</tt> - specifies an HTTP content type.
|
103
|
-
# Defaults to 'application/octet-stream'.
|
110
|
+
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
|
104
111
|
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
105
112
|
# Valid values are 'inline' and 'attachment' (default).
|
106
113
|
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
|
@@ -6,6 +6,6 @@
|
|
6
6
|
</h1>
|
7
7
|
<pre><%=h @exception.clean_message %></pre>
|
8
8
|
|
9
|
-
<%=
|
9
|
+
<%= render(:file => @rescues_path + "/_trace.erb") %>
|
10
10
|
|
11
|
-
<%=
|
11
|
+
<%= render(:file => @rescues_path + "/_request_and_response.erb") %>
|
@@ -15,7 +15,7 @@
|
|
15
15
|
|
16
16
|
<% @real_exception = @exception
|
17
17
|
@exception = @exception.original_exception || @exception %>
|
18
|
-
<%=
|
18
|
+
<%= render(:file => @rescues_path + "/_trace.erb") %>
|
19
19
|
<% @exception = @real_exception %>
|
20
20
|
|
21
|
-
<%=
|
21
|
+
<%= render(:file => @rescues_path + "/_request_and_response.erb") %>
|
@@ -15,6 +15,65 @@ module ActionController
|
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
|
+
# Superclass for ActionController functional tests. Functional tests allow you to
|
19
|
+
# test a single controller action per test method. This should not be confused with
|
20
|
+
# integration tests (see ActionController::IntegrationTest), which are more like
|
21
|
+
# "stories" that can involve multiple controllers and mutliple actions (i.e. multiple
|
22
|
+
# different HTTP requests).
|
23
|
+
#
|
24
|
+
# == Basic example
|
25
|
+
#
|
26
|
+
# Functional tests are written as follows:
|
27
|
+
# 1. First, one uses the +get+, +post+, +put+, +delete+ or +head+ method to simulate
|
28
|
+
# an HTTP request.
|
29
|
+
# 2. Then, one asserts whether the current state is as expected. "State" can be anything:
|
30
|
+
# the controller's HTTP response, the database contents, etc.
|
31
|
+
#
|
32
|
+
# For example:
|
33
|
+
#
|
34
|
+
# class BooksControllerTest < ActionController::TestCase
|
35
|
+
# def test_create
|
36
|
+
# # Simulate a POST response with the given HTTP parameters.
|
37
|
+
# post(:create, :book => { :title => "Love Hina" })
|
38
|
+
#
|
39
|
+
# # Assert that the controller tried to redirect us to
|
40
|
+
# # the created book's URI.
|
41
|
+
# assert_response :found
|
42
|
+
#
|
43
|
+
# # Assert that the controller really put the book in the database.
|
44
|
+
# assert_not_nil Book.find_by_title("Love Hina")
|
45
|
+
# end
|
46
|
+
# end
|
47
|
+
#
|
48
|
+
# == Special instance variables
|
49
|
+
#
|
50
|
+
# ActionController::TestCase will also automatically provide the following instance
|
51
|
+
# variables for use in the tests:
|
52
|
+
#
|
53
|
+
# <b>@controller</b>::
|
54
|
+
# The controller instance that will be tested.
|
55
|
+
# <b>@request</b>::
|
56
|
+
# An ActionController::TestRequest, representing the current HTTP
|
57
|
+
# request. You can modify this object before sending the HTTP request. For example,
|
58
|
+
# you might want to set some session properties before sending a GET request.
|
59
|
+
# <b>@response</b>::
|
60
|
+
# An ActionController::TestResponse object, representing the response
|
61
|
+
# of the last HTTP response. In the above example, <tt>@response</tt> becomes valid
|
62
|
+
# after calling +post+. If the various assert methods are not sufficient, then you
|
63
|
+
# may use this object to inspect the HTTP response in detail.
|
64
|
+
#
|
65
|
+
# (Earlier versions of Rails required each functional test to subclass
|
66
|
+
# Test::Unit::TestCase and define @controller, @request, @response in +setup+.)
|
67
|
+
#
|
68
|
+
# == Controller is automatically inferred
|
69
|
+
#
|
70
|
+
# ActionController::TestCase will automatically infer the controller under test
|
71
|
+
# from the test class name. If the controller cannot be inferred from the test
|
72
|
+
# class name, you can explicity set it with +tests+.
|
73
|
+
#
|
74
|
+
# class SpecialEdgeCaseWidgetsControllerTest < ActionController::TestCase
|
75
|
+
# tests WidgetController
|
76
|
+
# end
|
18
77
|
class TestCase < ActiveSupport::TestCase
|
19
78
|
# When the request.remote_addr remains the default for testing, which is 0.0.0.0, the exception is simply raised inline
|
20
79
|
# (bystepping the regular exception handling from rescue_action). If the request.remote_addr is anything else, the regular
|
@@ -25,7 +84,7 @@ module ActionController
|
|
25
84
|
module RaiseActionExceptions
|
26
85
|
attr_accessor :exception
|
27
86
|
|
28
|
-
def
|
87
|
+
def rescue_action_without_handler(e)
|
29
88
|
self.exception = e
|
30
89
|
|
31
90
|
if request.remote_addr == "0.0.0.0"
|
@@ -41,6 +100,8 @@ module ActionController
|
|
41
100
|
@@controller_class = nil
|
42
101
|
|
43
102
|
class << self
|
103
|
+
# Sets the controller class name. Useful if the name can't be inferred from test class.
|
104
|
+
# Expects +controller_class+ as a constant. Example: <tt>tests WidgetController</tt>.
|
44
105
|
def tests(controller_class)
|
45
106
|
self.controller_class = controller_class
|
46
107
|
end
|
@@ -73,6 +134,9 @@ module ActionController
|
|
73
134
|
@controller = self.class.controller_class.new
|
74
135
|
@controller.request = @request = TestRequest.new
|
75
136
|
@response = TestResponse.new
|
137
|
+
|
138
|
+
@controller.params = {}
|
139
|
+
@controller.send(:initialize_current_url)
|
76
140
|
end
|
77
141
|
|
78
142
|
# Cause the action to be rescued according to the regular rules for rescue_action when the visitor is not local
|
@@ -80,4 +144,4 @@ module ActionController
|
|
80
144
|
@request.remote_addr = '208.77.188.166' # example.com
|
81
145
|
end
|
82
146
|
end
|
83
|
-
end
|
147
|
+
end
|