halorgium-actionpack 3.0.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
@@ -0,0 +1,45 @@
|
|
1
|
+
module ActionController #:nodoc:
|
2
|
+
module SessionManagement #:nodoc:
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include ActionController::Configuration
|
6
|
+
|
7
|
+
module ClassMethods
|
8
|
+
# Set the session store to be used for keeping the session data between requests.
|
9
|
+
# By default, sessions are stored in browser cookies (<tt>:cookie_store</tt>),
|
10
|
+
# but you can also specify one of the other included stores (<tt>:active_record_store</tt>,
|
11
|
+
# <tt>:mem_cache_store</tt>, or your own custom class.
|
12
|
+
def session_store=(store)
|
13
|
+
if store == :active_record_store
|
14
|
+
self.session_store = ActiveRecord::SessionStore
|
15
|
+
else
|
16
|
+
@@session_store = store.is_a?(Symbol) ?
|
17
|
+
ActionDispatch::Session.const_get(store.to_s.camelize) :
|
18
|
+
store
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Returns the session store class currently used.
|
23
|
+
def session_store
|
24
|
+
if defined? @@session_store
|
25
|
+
@@session_store
|
26
|
+
else
|
27
|
+
ActionDispatch::Session::CookieStore
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def session=(options = {})
|
32
|
+
self.session_store = nil if options.delete(:disabled)
|
33
|
+
session_options.merge!(options)
|
34
|
+
end
|
35
|
+
|
36
|
+
def session(*args)
|
37
|
+
ActiveSupport::Deprecation.warn(
|
38
|
+
"Disabling sessions for a single controller has been deprecated. " +
|
39
|
+
"Sessions are now lazy loaded. So if you don't access them, " +
|
40
|
+
"consider them off. You can still modify the session cookie " +
|
41
|
+
"options with request.session_options.", caller)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
require 'active_support/core_ext/string/bytesize'
|
2
|
+
|
3
|
+
module ActionController #:nodoc:
|
4
|
+
# Methods for sending arbitrary data and for streaming files to the browser,
|
5
|
+
# instead of rendering.
|
6
|
+
module Streaming
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
include ActionController::RenderingController
|
10
|
+
|
11
|
+
DEFAULT_SEND_FILE_OPTIONS = {
|
12
|
+
:type => 'application/octet-stream'.freeze,
|
13
|
+
:disposition => 'attachment'.freeze,
|
14
|
+
:stream => true,
|
15
|
+
:buffer_size => 4096,
|
16
|
+
:x_sendfile => false
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
X_SENDFILE_HEADER = 'X-Sendfile'.freeze
|
20
|
+
|
21
|
+
protected
|
22
|
+
# Sends the file, by default streaming it 4096 bytes at a time. This way the
|
23
|
+
# whole file doesn't need to be read into memory at once. This makes it
|
24
|
+
# feasible to send even large files. You can optionally turn off streaming
|
25
|
+
# and send the whole file at once.
|
26
|
+
#
|
27
|
+
# Be careful to sanitize the path parameter if it is coming from a web
|
28
|
+
# page. <tt>send_file(params[:path])</tt> allows a malicious user to
|
29
|
+
# download any file on your server.
|
30
|
+
#
|
31
|
+
# Options:
|
32
|
+
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
33
|
+
# Defaults to <tt>File.basename(path)</tt>.
|
34
|
+
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
|
35
|
+
# either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
|
36
|
+
# * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
|
37
|
+
# is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
|
38
|
+
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
39
|
+
# Valid values are 'inline' and 'attachment' (default).
|
40
|
+
# * <tt>:stream</tt> - whether to send the file to the user agent as it is read (+true+)
|
41
|
+
# or to read the entire file before sending (+false+). Defaults to +true+.
|
42
|
+
# * <tt>:buffer_size</tt> - specifies size (in bytes) of the buffer used to stream the file.
|
43
|
+
# Defaults to 4096.
|
44
|
+
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
|
45
|
+
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
|
46
|
+
# the URL, which is necessary for i18n filenames on certain browsers
|
47
|
+
# (setting <tt>:filename</tt> overrides this option).
|
48
|
+
# * <tt>:x_sendfile</tt> - uses X-Sendfile to send the file when set to +true+. This is currently
|
49
|
+
# only available with Lighttpd/Apache2 and specific modules installed and activated. Since this
|
50
|
+
# uses the web server to send the file, this may lower memory consumption on your server and
|
51
|
+
# it will not block your application for further requests.
|
52
|
+
# See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and
|
53
|
+
# http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+.
|
54
|
+
#
|
55
|
+
# The default Content-Type and Content-Disposition headers are
|
56
|
+
# set to download arbitrary binary files in as many browsers as
|
57
|
+
# possible. IE versions 4, 5, 5.5, and 6 are all known to have
|
58
|
+
# a variety of quirks (especially when downloading over SSL).
|
59
|
+
#
|
60
|
+
# Simple download:
|
61
|
+
#
|
62
|
+
# send_file '/path/to.zip'
|
63
|
+
#
|
64
|
+
# Show a JPEG in the browser:
|
65
|
+
#
|
66
|
+
# send_file '/path/to.jpeg', :type => 'image/jpeg', :disposition => 'inline'
|
67
|
+
#
|
68
|
+
# Show a 404 page in the browser:
|
69
|
+
#
|
70
|
+
# send_file '/path/to/404.html', :type => 'text/html; charset=utf-8', :status => 404
|
71
|
+
#
|
72
|
+
# Read about the other Content-* HTTP headers if you'd like to
|
73
|
+
# provide the user with more information (such as Content-Description) in
|
74
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
|
75
|
+
#
|
76
|
+
# Also be aware that the document may be cached by proxies and browsers.
|
77
|
+
# The Pragma and Cache-Control headers declare how the file may be cached
|
78
|
+
# by intermediaries. They default to require clients to validate with
|
79
|
+
# the server before releasing cached responses. See
|
80
|
+
# http://www.mnot.net/cache_docs/ for an overview of web caching and
|
81
|
+
# http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
|
82
|
+
# for the Cache-Control header spec.
|
83
|
+
def send_file(path, options = {}) #:doc:
|
84
|
+
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
|
85
|
+
|
86
|
+
options[:length] ||= File.size(path)
|
87
|
+
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
88
|
+
send_file_headers! options
|
89
|
+
|
90
|
+
@performed_render = false
|
91
|
+
|
92
|
+
if options[:x_sendfile]
|
93
|
+
logger.info "Sending #{X_SENDFILE_HEADER} header #{path}" if logger
|
94
|
+
head options[:status], X_SENDFILE_HEADER => path
|
95
|
+
else
|
96
|
+
if options[:stream]
|
97
|
+
# TODO : Make render :text => proc {} work with the new base
|
98
|
+
render :status => options[:status], :text => Proc.new { |response, output|
|
99
|
+
logger.info "Streaming file #{path}" unless logger.nil?
|
100
|
+
len = options[:buffer_size] || 4096
|
101
|
+
File.open(path, 'rb') do |file|
|
102
|
+
while buf = file.read(len)
|
103
|
+
output.write(buf)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
}
|
107
|
+
else
|
108
|
+
logger.info "Sending file #{path}" unless logger.nil?
|
109
|
+
File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read }
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
# Sends the given binary data to the browser. This method is similar to
|
115
|
+
# <tt>render :text => data</tt>, but also allows you to specify whether
|
116
|
+
# the browser should display the response as a file attachment (i.e. in a
|
117
|
+
# download dialog) or as inline data. You may also set the content type,
|
118
|
+
# the apparent file name, and other things.
|
119
|
+
#
|
120
|
+
# Options:
|
121
|
+
# * <tt>:filename</tt> - suggests a filename for the browser to use.
|
122
|
+
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
|
123
|
+
# either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
|
124
|
+
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
125
|
+
# Valid values are 'inline' and 'attachment' (default).
|
126
|
+
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
|
127
|
+
#
|
128
|
+
# Generic data download:
|
129
|
+
#
|
130
|
+
# send_data buffer
|
131
|
+
#
|
132
|
+
# Download a dynamically-generated tarball:
|
133
|
+
#
|
134
|
+
# send_data generate_tgz('dir'), :filename => 'dir.tgz'
|
135
|
+
#
|
136
|
+
# Display an image Active Record in the browser:
|
137
|
+
#
|
138
|
+
# send_data image.data, :type => image.content_type, :disposition => 'inline'
|
139
|
+
#
|
140
|
+
# See +send_file+ for more information on HTTP Content-* headers and caching.
|
141
|
+
#
|
142
|
+
# <b>Tip:</b> if you want to stream large amounts of on-the-fly generated
|
143
|
+
# data to the browser, then use <tt>render :text => proc { ... }</tt>
|
144
|
+
# instead. See ActionController::Base#render for more information.
|
145
|
+
def send_data(data, options = {}) #:doc:
|
146
|
+
logger.info "Sending data #{options[:filename]}" if logger
|
147
|
+
send_file_headers! options.merge(:length => data.bytesize)
|
148
|
+
render :status => options[:status], :text => data
|
149
|
+
end
|
150
|
+
|
151
|
+
private
|
152
|
+
def send_file_headers!(options)
|
153
|
+
options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options))
|
154
|
+
[:length, :type, :disposition].each do |arg|
|
155
|
+
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
|
156
|
+
end
|
157
|
+
|
158
|
+
disposition = options[:disposition].dup || 'attachment'
|
159
|
+
|
160
|
+
disposition <<= %(; filename="#{options[:filename]}") if options[:filename]
|
161
|
+
|
162
|
+
content_type = options[:type]
|
163
|
+
|
164
|
+
if content_type.is_a?(Symbol)
|
165
|
+
raise ArgumentError, "Unknown MIME type #{options[:type]}" unless Mime::EXTENSION_LOOKUP.key?(content_type.to_s)
|
166
|
+
self.content_type = Mime::Type.lookup_by_extension(content_type.to_s)
|
167
|
+
else
|
168
|
+
self.content_type = content_type
|
169
|
+
end
|
170
|
+
|
171
|
+
headers.merge!(
|
172
|
+
'Content-Length' => options[:length].to_s,
|
173
|
+
'Content-Disposition' => disposition,
|
174
|
+
'Content-Transfer-Encoding' => 'binary'
|
175
|
+
)
|
176
|
+
|
177
|
+
response.sending_file = true
|
178
|
+
|
179
|
+
# Fix a problem with IE 6.0 on opening downloaded files:
|
180
|
+
# If Cache-Control: no-cache is set (which Rails does by default),
|
181
|
+
# IE removes the file it just downloaded from its cache immediately
|
182
|
+
# after it displays the "open/save" dialog, which means that if you
|
183
|
+
# hit "open" the file isn't there anymore when the application that
|
184
|
+
# is called for handling the download is run, so let's workaround that
|
185
|
+
response.cache_control[:public] ||= false
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module ActionController
|
2
|
+
module Testing
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include RackConvenience
|
6
|
+
|
7
|
+
# OMG MEGA HAX
|
8
|
+
def process_with_new_base_test(request, response)
|
9
|
+
@_request = request
|
10
|
+
@_response = response
|
11
|
+
@_response.request = request
|
12
|
+
ret = process(request.parameters[:action])
|
13
|
+
@_response.body ||= self.response_body
|
14
|
+
@_response.prepare!
|
15
|
+
set_test_assigns
|
16
|
+
ret
|
17
|
+
end
|
18
|
+
|
19
|
+
def set_test_assigns
|
20
|
+
@assigns = {}
|
21
|
+
(instance_variable_names - self.class.protected_instance_variables).each do |var|
|
22
|
+
name, value = var[1..-1], instance_variable_get(var)
|
23
|
+
@assigns[name] = value
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# TODO : Rewrite tests using controller.headers= to use Rack env
|
28
|
+
def headers=(new_headers)
|
29
|
+
@_response ||= ActionDispatch::Response.new
|
30
|
+
@_response.headers.replace(new_headers)
|
31
|
+
end
|
32
|
+
|
33
|
+
module ClassMethods
|
34
|
+
def before_filters
|
35
|
+
_process_action_callbacks.find_all{|x| x.kind == :before}.map{|x| x.name}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
module ActionController
|
2
|
+
module UrlFor
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include RackConvenience
|
6
|
+
|
7
|
+
# Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
|
8
|
+
# the form of a hash, just like the one you would use for url_for directly. Example:
|
9
|
+
#
|
10
|
+
# def default_url_options(options)
|
11
|
+
# { :project => @project.active? ? @project.url_name : "unknown" }
|
12
|
+
# end
|
13
|
+
#
|
14
|
+
# As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the
|
15
|
+
# urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set
|
16
|
+
# by this method.
|
17
|
+
def default_url_options(options = nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
def rewrite_options(options) #:nodoc:
|
21
|
+
if defaults = default_url_options(options)
|
22
|
+
defaults.merge(options)
|
23
|
+
else
|
24
|
+
options
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
def url_for(options = {})
|
29
|
+
options ||= {}
|
30
|
+
case options
|
31
|
+
when String
|
32
|
+
options
|
33
|
+
when Hash
|
34
|
+
@url ||= UrlRewriter.new(request, params)
|
35
|
+
@url.rewrite(rewrite_options(options))
|
36
|
+
else
|
37
|
+
polymorphic_url(options)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
module ActionController #:nodoc:
|
2
|
+
module Verification #:nodoc:
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
include AbstractController::Callbacks, Session, Flash, RenderingController
|
6
|
+
|
7
|
+
# This module provides a class-level method for specifying that certain
|
8
|
+
# actions are guarded against being called without certain prerequisites
|
9
|
+
# being met. This is essentially a special kind of before_filter.
|
10
|
+
#
|
11
|
+
# An action may be guarded against being invoked without certain request
|
12
|
+
# parameters being set, or without certain session values existing.
|
13
|
+
#
|
14
|
+
# When a verification is violated, values may be inserted into the flash, and
|
15
|
+
# a specified redirection is triggered. If no specific action is configured,
|
16
|
+
# verification failures will by default result in a 400 Bad Request response.
|
17
|
+
#
|
18
|
+
# Usage:
|
19
|
+
#
|
20
|
+
# class GlobalController < ActionController::Base
|
21
|
+
# # Prevent the #update_settings action from being invoked unless
|
22
|
+
# # the 'admin_privileges' request parameter exists. The
|
23
|
+
# # settings action will be redirected to in current controller
|
24
|
+
# # if verification fails.
|
25
|
+
# verify :params => "admin_privileges", :only => :update_post,
|
26
|
+
# :redirect_to => { :action => "settings" }
|
27
|
+
#
|
28
|
+
# # Disallow a post from being updated if there was no information
|
29
|
+
# # submitted with the post, and if there is no active post in the
|
30
|
+
# # session, and if there is no "note" key in the flash. The route
|
31
|
+
# # named category_url will be redirected to if verification fails.
|
32
|
+
#
|
33
|
+
# verify :params => "post", :session => "post", "flash" => "note",
|
34
|
+
# :only => :update_post,
|
35
|
+
# :add_flash => { "alert" => "Failed to create your message" },
|
36
|
+
# :redirect_to => :category_url
|
37
|
+
#
|
38
|
+
# Note that these prerequisites are not business rules. They do not examine
|
39
|
+
# the content of the session or the parameters. That level of validation should
|
40
|
+
# be encapsulated by your domain model or helper methods in the controller.
|
41
|
+
module ClassMethods
|
42
|
+
# Verify the given actions so that if certain prerequisites are not met,
|
43
|
+
# the user is redirected to a different action. The +options+ parameter
|
44
|
+
# is a hash consisting of the following key/value pairs:
|
45
|
+
#
|
46
|
+
# <tt>:params</tt>::
|
47
|
+
# a single key or an array of keys that must be in the <tt>params</tt>
|
48
|
+
# hash in order for the action(s) to be safely called.
|
49
|
+
# <tt>:session</tt>::
|
50
|
+
# a single key or an array of keys that must be in the <tt>session</tt>
|
51
|
+
# in order for the action(s) to be safely called.
|
52
|
+
# <tt>:flash</tt>::
|
53
|
+
# a single key or an array of keys that must be in the flash in order
|
54
|
+
# for the action(s) to be safely called.
|
55
|
+
# <tt>:method</tt>::
|
56
|
+
# a single key or an array of keys--any one of which must match the
|
57
|
+
# current request method in order for the action(s) to be safely called.
|
58
|
+
# (The key should be a symbol: <tt>:get</tt> or <tt>:post</tt>, for
|
59
|
+
# example.)
|
60
|
+
# <tt>:xhr</tt>::
|
61
|
+
# true/false option to ensure that the request is coming from an Ajax
|
62
|
+
# call or not.
|
63
|
+
# <tt>:add_flash</tt>::
|
64
|
+
# a hash of name/value pairs that should be merged into the session's
|
65
|
+
# flash if the prerequisites cannot be satisfied.
|
66
|
+
# <tt>:add_headers</tt>::
|
67
|
+
# a hash of name/value pairs that should be merged into the response's
|
68
|
+
# headers hash if the prerequisites cannot be satisfied.
|
69
|
+
# <tt>:redirect_to</tt>::
|
70
|
+
# the redirection parameters to be used when redirecting if the
|
71
|
+
# prerequisites cannot be satisfied. You can redirect either to named
|
72
|
+
# route or to the action in some controller.
|
73
|
+
# <tt>:render</tt>::
|
74
|
+
# the render parameters to be used when the prerequisites cannot be satisfied.
|
75
|
+
# <tt>:only</tt>::
|
76
|
+
# only apply this verification to the actions specified in the associated
|
77
|
+
# array (may also be a single value).
|
78
|
+
# <tt>:except</tt>::
|
79
|
+
# do not apply this verification to the actions specified in the associated
|
80
|
+
# array (may also be a single value).
|
81
|
+
def verify(options={})
|
82
|
+
before_filter :only => options[:only], :except => options[:except] do
|
83
|
+
verify_action options
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
private
|
89
|
+
|
90
|
+
def verify_action(options) #:nodoc:
|
91
|
+
if prereqs_invalid?(options)
|
92
|
+
flash.update(options[:add_flash]) if options[:add_flash]
|
93
|
+
response.headers.merge!(options[:add_headers]) if options[:add_headers]
|
94
|
+
apply_remaining_actions(options) unless performed?
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def prereqs_invalid?(options) # :nodoc:
|
99
|
+
verify_presence_of_keys_in_hash_flash_or_params(options) ||
|
100
|
+
verify_method(options) ||
|
101
|
+
verify_request_xhr_status(options)
|
102
|
+
end
|
103
|
+
|
104
|
+
def verify_presence_of_keys_in_hash_flash_or_params(options) # :nodoc:
|
105
|
+
[*options[:params] ].find { |v| v && params[v.to_sym].nil? } ||
|
106
|
+
[*options[:session]].find { |v| session[v].nil? } ||
|
107
|
+
[*options[:flash] ].find { |v| flash[v].nil? }
|
108
|
+
end
|
109
|
+
|
110
|
+
def verify_method(options) # :nodoc:
|
111
|
+
[*options[:method]].all? { |v| request.method != v.to_sym } if options[:method]
|
112
|
+
end
|
113
|
+
|
114
|
+
def verify_request_xhr_status(options) # :nodoc:
|
115
|
+
request.xhr? != options[:xhr] unless options[:xhr].nil?
|
116
|
+
end
|
117
|
+
|
118
|
+
def apply_redirect_to(redirect_to_option) # :nodoc:
|
119
|
+
(redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.__send__(redirect_to_option) : redirect_to_option
|
120
|
+
end
|
121
|
+
|
122
|
+
def apply_remaining_actions(options) # :nodoc:
|
123
|
+
case
|
124
|
+
when options[:render] ; render(options[:render])
|
125
|
+
when options[:redirect_to] ; redirect_to(apply_redirect_to(options[:redirect_to]))
|
126
|
+
else head(:bad_request)
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|