actionpack 3.0.0.beta → 3.0.0.beta2
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 +291 -260
- data/lib/abstract_controller.rb +5 -2
- data/lib/abstract_controller/assigns.rb +21 -0
- data/lib/abstract_controller/base.rb +13 -5
- data/lib/abstract_controller/collector.rb +2 -0
- data/lib/abstract_controller/helpers.rb +4 -14
- data/lib/abstract_controller/layouts.rb +50 -99
- data/lib/abstract_controller/logger.rb +2 -2
- data/lib/abstract_controller/rendering.rb +105 -173
- data/lib/abstract_controller/view_paths.rb +69 -0
- data/lib/action_controller.rb +1 -2
- data/lib/action_controller/base.rb +10 -32
- data/lib/action_controller/caching.rb +19 -18
- data/lib/action_controller/caching/actions.rb +17 -11
- data/lib/action_controller/caching/fragments.rb +5 -17
- data/lib/action_controller/caching/pages.rb +24 -24
- data/lib/action_controller/caching/sweeping.rb +1 -3
- data/lib/action_controller/deprecated.rb +0 -2
- data/lib/action_controller/deprecated/base.rb +143 -0
- data/lib/action_controller/metal.rb +29 -26
- data/lib/action_controller/metal/compatibility.rb +18 -87
- data/lib/action_controller/metal/cookies.rb +0 -1
- data/lib/action_controller/metal/head.rb +1 -0
- data/lib/action_controller/metal/helpers.rb +2 -2
- data/lib/action_controller/metal/hide_actions.rb +4 -6
- data/lib/action_controller/metal/http_authentication.rb +18 -33
- data/lib/action_controller/metal/implicit_render.rb +21 -0
- data/lib/action_controller/metal/instrumentation.rb +1 -1
- data/lib/action_controller/metal/mime_responds.rb +2 -1
- data/lib/action_controller/metal/rack_delegation.rb +3 -8
- data/lib/action_controller/metal/redirecting.rb +2 -1
- data/lib/action_controller/metal/renderers.rb +4 -2
- data/lib/action_controller/metal/rendering.rb +31 -44
- data/lib/action_controller/metal/request_forgery_protection.rb +41 -4
- data/lib/action_controller/metal/responder.rb +2 -0
- data/lib/action_controller/metal/session_management.rb +0 -36
- data/lib/action_controller/metal/streaming.rb +20 -47
- data/lib/action_controller/metal/testing.rb +0 -1
- data/lib/action_controller/metal/url_for.rb +11 -148
- data/lib/action_controller/middleware.rb +2 -1
- data/lib/action_controller/polymorphic_routes.rb +1 -2
- data/lib/action_controller/railtie.rb +63 -10
- data/lib/action_controller/railties/{subscriber.rb → log_subscriber.rb} +5 -12
- data/lib/action_controller/railties/url_helpers.rb +14 -0
- data/lib/action_controller/record_identifier.rb +20 -1
- data/lib/action_controller/test_case.rb +123 -12
- data/lib/action_dispatch.rb +1 -0
- data/lib/action_dispatch/http/cache.rb +20 -3
- data/lib/action_dispatch/http/filter_parameters.rb +40 -25
- data/lib/action_dispatch/http/mime_negotiation.rb +6 -17
- data/lib/action_dispatch/http/mime_type.rb +2 -7
- data/lib/action_dispatch/http/request.rb +12 -33
- data/lib/action_dispatch/http/response.rb +35 -15
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/http/url.rb +5 -32
- data/lib/action_dispatch/middleware/callbacks.rb +1 -1
- data/lib/action_dispatch/middleware/cookies.rb +4 -3
- data/lib/action_dispatch/middleware/params_parser.rb +4 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +51 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +6 -8
- data/lib/action_dispatch/middleware/show_exceptions.rb +0 -14
- data/lib/action_dispatch/middleware/stack.rb +6 -2
- data/lib/action_dispatch/railtie.rb +3 -1
- data/lib/action_dispatch/routing.rb +2 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +35 -7
- data/lib/action_dispatch/routing/mapper.rb +134 -48
- data/lib/action_dispatch/routing/route.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +217 -158
- data/lib/action_dispatch/routing/url_for.rb +139 -0
- data/lib/action_dispatch/testing/assertions/response.rb +14 -61
- data/lib/action_dispatch/testing/assertions/routing.rb +25 -14
- data/lib/action_dispatch/testing/integration.rb +32 -50
- data/lib/action_dispatch/testing/performance_test.rb +3 -1
- data/lib/action_dispatch/testing/test_process.rb +2 -0
- data/lib/action_dispatch/testing/test_request.rb +2 -0
- data/lib/action_pack/version.rb +4 -3
- data/lib/action_view.rb +11 -6
- data/lib/action_view/base.rb +33 -121
- data/lib/action_view/context.rb +0 -2
- data/lib/action_view/helpers.rb +26 -23
- data/lib/action_view/helpers/active_model_helper.rb +28 -18
- data/lib/action_view/helpers/asset_tag_helper.rb +109 -54
- data/lib/action_view/helpers/atom_feed_helper.rb +2 -2
- data/lib/action_view/helpers/cache_helper.rb +22 -1
- data/lib/action_view/helpers/capture_helper.rb +22 -22
- data/lib/action_view/helpers/date_helper.rb +6 -5
- data/lib/action_view/helpers/form_helper.rb +78 -63
- data/lib/action_view/helpers/form_options_helper.rb +6 -4
- data/lib/action_view/helpers/form_tag_helper.rb +26 -15
- data/lib/action_view/helpers/javascript_helper.rb +90 -10
- data/lib/action_view/helpers/number_helper.rb +315 -118
- data/lib/action_view/helpers/prototype_helper.rb +19 -46
- data/lib/action_view/helpers/record_tag_helper.rb +4 -4
- data/lib/action_view/helpers/tag_helper.rb +7 -24
- data/lib/action_view/helpers/text_helper.rb +8 -7
- data/lib/action_view/helpers/translation_helper.rb +7 -5
- data/lib/action_view/helpers/url_helper.rb +19 -16
- data/lib/action_view/locale/en.yml +45 -6
- data/lib/action_view/lookup_context.rb +190 -0
- data/lib/action_view/paths.rb +22 -63
- data/lib/action_view/railtie.rb +14 -4
- data/lib/action_view/railties/{subscriber.rb → log_subscriber.rb} +1 -1
- data/lib/action_view/render/layouts.rb +73 -0
- data/lib/action_view/render/partials.rb +15 -41
- data/lib/action_view/render/rendering.rb +27 -78
- data/lib/action_view/template.rb +20 -24
- data/lib/action_view/template/error.rb +22 -2
- data/lib/action_view/template/handlers/erb.rb +33 -9
- data/lib/action_view/template/handlers/rjs.rb +1 -2
- data/lib/action_view/template/resolver.rb +46 -104
- data/lib/action_view/template/text.rb +5 -12
- data/lib/action_view/test_case.rb +14 -23
- metadata +83 -40
- data/lib/abstract_controller/compatibility.rb +0 -18
- data/lib/abstract_controller/localized_cache.rb +0 -49
- data/lib/action_controller/metal/configuration.rb +0 -28
- data/lib/action_controller/url_rewriter.rb +0 -76
@@ -20,7 +20,7 @@ module ActionController
|
|
20
20
|
:params => request.filtered_parameters,
|
21
21
|
:formats => request.formats.map(&:to_sym),
|
22
22
|
:method => request.method,
|
23
|
-
:path => (request.
|
23
|
+
:path => (request.fullpath rescue "unknown")
|
24
24
|
}
|
25
25
|
|
26
26
|
ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup)
|
@@ -261,7 +261,8 @@ module ActionController #:nodoc:
|
|
261
261
|
block.call(collector) if block_given?
|
262
262
|
|
263
263
|
if format = request.negotiate_mime(collector.order)
|
264
|
-
self.
|
264
|
+
self.content_type ||= format.to_s
|
265
|
+
lookup_context.freeze_formats([format.to_sym])
|
265
266
|
collector.response_for(format)
|
266
267
|
else
|
267
268
|
head :not_acceptable
|
@@ -5,15 +5,10 @@ module ActionController
|
|
5
5
|
module RackDelegation
|
6
6
|
extend ActiveSupport::Concern
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
delegate :headers, :status=, :location=, :content_type=,
|
11
|
-
:status, :location, :content_type, :to => "@_response"
|
12
|
-
attr_internal :request
|
13
|
-
end
|
8
|
+
delegate :headers, :status=, :location=, :content_type=,
|
9
|
+
:status, :location, :content_type, :to => "@_response"
|
14
10
|
|
15
|
-
def dispatch(action,
|
16
|
-
@_request = ActionDispatch::Request.new(env)
|
11
|
+
def dispatch(action, request)
|
17
12
|
@_response = ActionDispatch::Response.new
|
18
13
|
@_response.request = request
|
19
14
|
super
|
@@ -11,6 +11,7 @@ module ActionController
|
|
11
11
|
extend ActiveSupport::Concern
|
12
12
|
|
13
13
|
include AbstractController::Logger
|
14
|
+
include ActionController::RackDelegation
|
14
15
|
include ActionController::UrlFor
|
15
16
|
|
16
17
|
# Redirects the browser to the target specified in +options+. This parameter can take one of three forms:
|
@@ -75,7 +76,7 @@ module ActionController
|
|
75
76
|
# The scheme name consist of a letter followed by any combination of
|
76
77
|
# letters, digits, and the plus ("+"), period ("."), or hyphen ("-")
|
77
78
|
# characters; and is terminated by a colon (":").
|
78
|
-
when %r{^\w[\w
|
79
|
+
when %r{^\w[\w+.-]*:.*}
|
79
80
|
options
|
80
81
|
when String
|
81
82
|
request.protocol + request.host_with_port + options
|
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'active_support/core_ext/class/attribute'
|
2
|
+
require 'active_support/core_ext/object/blank'
|
2
3
|
|
3
4
|
module ActionController
|
4
5
|
def self.add_renderer(key, &block)
|
@@ -19,7 +20,7 @@ module ActionController
|
|
19
20
|
<<-RUBY_EVAL
|
20
21
|
if options.key?(:#{name})
|
21
22
|
_process_options(options)
|
22
|
-
return _render_option_#{name}(options
|
23
|
+
return _render_option_#{name}(options.delete(:#{name}), options)
|
23
24
|
end
|
24
25
|
RUBY_EVAL
|
25
26
|
end
|
@@ -87,8 +88,9 @@ module ActionController
|
|
87
88
|
end
|
88
89
|
|
89
90
|
add :update do |proc, options|
|
91
|
+
view_context = self.view_context
|
90
92
|
generator = ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.new(view_context, &proc)
|
91
|
-
self.content_type
|
93
|
+
self.content_type = Mime::JS
|
92
94
|
self.response_body = generator.to_s
|
93
95
|
end
|
94
96
|
end
|
@@ -2,68 +2,55 @@ module ActionController
|
|
2
2
|
module Rendering
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
include AbstractController::LocalizedCache
|
8
|
-
end
|
5
|
+
include ActionController::RackDelegation
|
6
|
+
include AbstractController::Rendering
|
9
7
|
|
10
|
-
|
11
|
-
|
8
|
+
# Before processing, set the request formats in current controller formats.
|
9
|
+
def process_action(*) #:nodoc:
|
10
|
+
self.formats = request.formats.map { |x| x.to_sym }
|
12
11
|
super
|
13
12
|
end
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
end
|
19
|
-
|
20
|
-
args << {} unless args.last.is_a?(Hash)
|
21
|
-
super(*args)
|
22
|
-
self.content_type ||= args.last[:_template].mime_type.to_s
|
23
|
-
response_body
|
24
|
-
end
|
25
|
-
|
26
|
-
def render_to_body(options)
|
27
|
-
_process_options(options)
|
14
|
+
# Check for double render errors and set the content_type after rendering.
|
15
|
+
def render(*args) #:nodoc:
|
16
|
+
raise ::AbstractController::DoubleRenderError if response_body
|
28
17
|
super
|
18
|
+
self.content_type ||= Mime[formats.first].to_s
|
19
|
+
response_body
|
29
20
|
end
|
30
21
|
|
31
22
|
private
|
32
23
|
|
33
|
-
|
34
|
-
|
35
|
-
options
|
36
|
-
|
24
|
+
# Normalize arguments by catching blocks and setting them on :update.
|
25
|
+
def _normalize_args(action=nil, options={}, &blk) #:nodoc:
|
26
|
+
options = super
|
27
|
+
options[:update] = blk if block_given?
|
28
|
+
options
|
37
29
|
end
|
38
30
|
|
39
|
-
|
40
|
-
|
31
|
+
# Normalize both text and status options.
|
32
|
+
def _normalize_options(options) #:nodoc:
|
33
|
+
if options.key?(:text) && options[:text].respond_to?(:to_text)
|
34
|
+
options[:text] = options[:text].to_text
|
35
|
+
end
|
36
|
+
|
37
|
+
if options[:status]
|
38
|
+
options[:status] = Rack::Utils.status_code(options[:status])
|
39
|
+
end
|
40
|
+
|
41
|
+
super
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
+
# Process controller specific options, as status, content-type and location.
|
45
|
+
def _process_options(options) #:nodoc:
|
44
46
|
status, content_type, location = options.values_at(:status, :content_type, :location)
|
47
|
+
|
45
48
|
self.status = status if status
|
46
49
|
self.content_type = content_type if content_type
|
47
50
|
self.headers["Location"] = url_for(location) if location
|
48
|
-
end
|
49
|
-
|
50
|
-
def _normalize_options(action=nil, options={}, &blk)
|
51
|
-
case action
|
52
|
-
when NilClass
|
53
|
-
when Hash
|
54
|
-
options = super(action.delete(:action), action)
|
55
|
-
when String, Symbol
|
56
|
-
options = super
|
57
|
-
else
|
58
|
-
options.merge! :partial => action
|
59
|
-
end
|
60
|
-
|
61
|
-
if options[:status]
|
62
|
-
options[:status] = Rack::Utils.status_code(options[:status])
|
63
|
-
end
|
64
51
|
|
65
|
-
|
66
|
-
options
|
52
|
+
super
|
67
53
|
end
|
54
|
+
|
68
55
|
end
|
69
56
|
end
|
@@ -12,11 +12,10 @@ module ActionController #:nodoc:
|
|
12
12
|
included do
|
13
13
|
# Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+
|
14
14
|
# sets it to <tt>:authenticity_token</tt> by default.
|
15
|
-
|
15
|
+
config.request_forgery_protection_token ||= :authenticity_token
|
16
16
|
|
17
17
|
# Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode.
|
18
|
-
|
19
|
-
self.allow_forgery_protection = true
|
18
|
+
config.allow_forgery_protection ||= true
|
20
19
|
|
21
20
|
helper_method :form_authenticity_token
|
22
21
|
helper_method :protect_against_forgery?
|
@@ -80,9 +79,47 @@ module ActionController #:nodoc:
|
|
80
79
|
self.request_forgery_protection_token ||= :authenticity_token
|
81
80
|
before_filter :verify_authenticity_token, options
|
82
81
|
end
|
82
|
+
|
83
|
+
def request_forgery_protection_token
|
84
|
+
config.request_forgery_protection_token
|
85
|
+
end
|
86
|
+
|
87
|
+
def request_forgery_protection_token=(val)
|
88
|
+
config.request_forgery_protection_token = val
|
89
|
+
end
|
90
|
+
|
91
|
+
def allow_forgery_protection
|
92
|
+
config.allow_forgery_protection
|
93
|
+
end
|
94
|
+
|
95
|
+
def allow_forgery_protection=(val)
|
96
|
+
config.allow_forgery_protection = val
|
97
|
+
end
|
83
98
|
end
|
84
99
|
|
85
100
|
protected
|
101
|
+
|
102
|
+
def protect_from_forgery(options = {})
|
103
|
+
self.request_forgery_protection_token ||= :authenticity_token
|
104
|
+
before_filter :verify_authenticity_token, options
|
105
|
+
end
|
106
|
+
|
107
|
+
def request_forgery_protection_token
|
108
|
+
config.request_forgery_protection_token
|
109
|
+
end
|
110
|
+
|
111
|
+
def request_forgery_protection_token=(val)
|
112
|
+
config.request_forgery_protection_token = val
|
113
|
+
end
|
114
|
+
|
115
|
+
def allow_forgery_protection
|
116
|
+
config.allow_forgery_protection
|
117
|
+
end
|
118
|
+
|
119
|
+
def allow_forgery_protection=(val)
|
120
|
+
config.allow_forgery_protection = val
|
121
|
+
end
|
122
|
+
|
86
123
|
# The actual before_filter that is used. Modify this to change how you handle unverified requests.
|
87
124
|
def verify_authenticity_token
|
88
125
|
verified_request? || raise(ActionController::InvalidAuthenticityToken)
|
@@ -109,7 +146,7 @@ module ActionController #:nodoc:
|
|
109
146
|
end
|
110
147
|
|
111
148
|
def protect_against_forgery?
|
112
|
-
|
149
|
+
config.allow_forgery_protection
|
113
150
|
end
|
114
151
|
end
|
115
152
|
end
|
@@ -2,44 +2,8 @@ module ActionController #:nodoc:
|
|
2
2
|
module SessionManagement #:nodoc:
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
|
-
include ActionController::Configuration
|
6
|
-
|
7
5
|
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
6
|
|
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
7
|
end
|
44
8
|
end
|
45
9
|
end
|
@@ -9,18 +9,13 @@ module ActionController #:nodoc:
|
|
9
9
|
DEFAULT_SEND_FILE_OPTIONS = {
|
10
10
|
:type => 'application/octet-stream'.freeze,
|
11
11
|
:disposition => 'attachment'.freeze,
|
12
|
-
:stream => true,
|
13
|
-
:buffer_size => 4096,
|
14
|
-
:x_sendfile => false
|
15
12
|
}.freeze
|
16
13
|
|
17
|
-
X_SENDFILE_HEADER = 'X-Sendfile'.freeze
|
18
|
-
|
19
14
|
protected
|
20
|
-
# Sends the file
|
21
|
-
#
|
22
|
-
#
|
23
|
-
#
|
15
|
+
# Sends the file. This uses a server-appropriate method (such as X-Sendfile)
|
16
|
+
# via the Rack::Sendfile middleware. The header to use is set via
|
17
|
+
# config.action_dispatch.x_sendfile_header, and defaults to "X-Sendfile".
|
18
|
+
# Your server can also configure this for you by setting the X-Sendfile-Type header.
|
24
19
|
#
|
25
20
|
# Be careful to sanitize the path parameter if it is coming from a web
|
26
21
|
# page. <tt>send_file(params[:path])</tt> allows a malicious user to
|
@@ -31,24 +26,12 @@ module ActionController #:nodoc:
|
|
31
26
|
# Defaults to <tt>File.basename(path)</tt>.
|
32
27
|
# * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
|
33
28
|
# either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
|
34
|
-
# * <tt>:length</tt> - used to manually override the length (in bytes) of the content that
|
35
|
-
# is going to be sent to the client. Defaults to <tt>File.size(path)</tt>.
|
36
29
|
# * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
|
37
30
|
# Valid values are 'inline' and 'attachment' (default).
|
38
|
-
# * <tt>:stream</tt> - whether to send the file to the user agent as it is read (+true+)
|
39
|
-
# or to read the entire file before sending (+false+). Defaults to +true+.
|
40
|
-
# * <tt>:buffer_size</tt> - specifies size (in bytes) of the buffer used to stream the file.
|
41
|
-
# Defaults to 4096.
|
42
31
|
# * <tt>:status</tt> - specifies the status code to send with the response. Defaults to '200 OK'.
|
43
32
|
# * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
|
44
33
|
# the URL, which is necessary for i18n filenames on certain browsers
|
45
34
|
# (setting <tt>:filename</tt> overrides this option).
|
46
|
-
# * <tt>:x_sendfile</tt> - uses X-Sendfile to send the file when set to +true+. This is currently
|
47
|
-
# only available with Lighttpd/Apache2 and specific modules installed and activated. Since this
|
48
|
-
# uses the web server to send the file, this may lower memory consumption on your server and
|
49
|
-
# it will not block your application for further requests.
|
50
|
-
# See http://blog.lighttpd.net/articles/2006/07/02/x-sendfile and
|
51
|
-
# http://tn123.ath.cx/mod_xsendfile/ for details. Defaults to +false+.
|
52
35
|
#
|
53
36
|
# The default Content-Type and Content-Disposition headers are
|
54
37
|
# set to download arbitrary binary files in as many browsers as
|
@@ -81,29 +64,16 @@ module ActionController #:nodoc:
|
|
81
64
|
def send_file(path, options = {}) #:doc:
|
82
65
|
raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
|
83
66
|
|
84
|
-
options[:length] ||= File.size(path)
|
85
67
|
options[:filename] ||= File.basename(path) unless options[:url_based_filename]
|
86
68
|
send_file_headers! options
|
87
69
|
|
88
|
-
@performed_render = false
|
89
|
-
|
90
70
|
if options[:x_sendfile]
|
91
|
-
|
92
|
-
else
|
93
|
-
if options[:stream]
|
94
|
-
# TODO : Make render :text => proc {} work with the new base
|
95
|
-
render :status => options[:status], :text => Proc.new { |response, output|
|
96
|
-
len = options[:buffer_size] || 4096
|
97
|
-
File.open(path, 'rb') do |file|
|
98
|
-
while buf = file.read(len)
|
99
|
-
output.write(buf)
|
100
|
-
end
|
101
|
-
end
|
102
|
-
}
|
103
|
-
else
|
104
|
-
File.open(path, 'rb') { |file| render :status => options[:status], :text => file.read }
|
105
|
-
end
|
71
|
+
ActiveSupport::Deprecation.warn(":x_sendfile is no longer needed in send_file", caller)
|
106
72
|
end
|
73
|
+
|
74
|
+
self.status = options[:status] || 200
|
75
|
+
self.content_type = options[:content_type] if options.key?(:content_type)
|
76
|
+
self.response_body = File.open(path, "rb")
|
107
77
|
end
|
108
78
|
|
109
79
|
# Sends the given binary data to the browser. This method is similar to
|
@@ -138,32 +108,35 @@ module ActionController #:nodoc:
|
|
138
108
|
# data to the browser, then use <tt>render :text => proc { ... }</tt>
|
139
109
|
# instead. See ActionController::Base#render for more information.
|
140
110
|
def send_data(data, options = {}) #:doc:
|
141
|
-
send_file_headers! options.
|
142
|
-
render
|
111
|
+
send_file_headers! options.dup
|
112
|
+
render options.slice(:status, :content_type).merge(:text => data)
|
143
113
|
end
|
144
114
|
|
145
115
|
private
|
146
116
|
def send_file_headers!(options)
|
147
117
|
options.update(DEFAULT_SEND_FILE_OPTIONS.merge(options))
|
148
|
-
[:
|
118
|
+
[:type, :disposition].each do |arg|
|
149
119
|
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
|
150
120
|
end
|
151
121
|
|
152
|
-
|
122
|
+
if options.key?(:length)
|
123
|
+
ActiveSupport::Deprecation.warn("You do not need to provide the file's length", caller)
|
124
|
+
end
|
153
125
|
|
154
|
-
disposition
|
126
|
+
disposition = options[:disposition]
|
127
|
+
disposition += %(; filename="#{options[:filename]}") if options[:filename]
|
155
128
|
|
156
129
|
content_type = options[:type]
|
157
130
|
|
158
131
|
if content_type.is_a?(Symbol)
|
159
|
-
|
160
|
-
|
132
|
+
extension = Mime[content_type]
|
133
|
+
raise ArgumentError, "Unknown MIME type #{options[:type]}" unless extension
|
134
|
+
self.content_type = extension
|
161
135
|
else
|
162
136
|
self.content_type = content_type
|
163
137
|
end
|
164
138
|
|
165
139
|
headers.merge!(
|
166
|
-
'Content-Length' => options[:length].to_s,
|
167
140
|
'Content-Disposition' => disposition,
|
168
141
|
'Content-Transfer-Encoding' => 'binary'
|
169
142
|
)
|
@@ -1,157 +1,20 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute'
|
2
|
-
|
3
1
|
module ActionController
|
4
|
-
# In <b>routes.rb</b> one defines URL-to-controller mappings, but the reverse
|
5
|
-
# is also possible: an URL can be generated from one of your routing definitions.
|
6
|
-
# URL generation functionality is centralized in this module.
|
7
|
-
#
|
8
|
-
# See ActionController::Routing and ActionController::Resources for general
|
9
|
-
# information about routing and routes.rb.
|
10
|
-
#
|
11
|
-
# <b>Tip:</b> If you need to generate URLs from your models or some other place,
|
12
|
-
# then ActionController::UrlFor is what you're looking for. Read on for
|
13
|
-
# an introduction.
|
14
|
-
#
|
15
|
-
# == URL generation from parameters
|
16
|
-
#
|
17
|
-
# As you may know, some functions - such as ActionController::Base#url_for
|
18
|
-
# and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
|
19
|
-
# of parameters. For example, you've probably had the chance to write code
|
20
|
-
# like this in one of your views:
|
21
|
-
#
|
22
|
-
# <%= link_to('Click here', :controller => 'users',
|
23
|
-
# :action => 'new', :message => 'Welcome!') %>
|
24
|
-
#
|
25
|
-
# #=> Generates a link to: /users/new?message=Welcome%21
|
26
|
-
#
|
27
|
-
# link_to, and all other functions that require URL generation functionality,
|
28
|
-
# actually use ActionController::UrlFor under the hood. And in particular,
|
29
|
-
# they use the ActionController::UrlFor#url_for method. One can generate
|
30
|
-
# the same path as the above example by using the following code:
|
31
|
-
#
|
32
|
-
# include UrlFor
|
33
|
-
# url_for(:controller => 'users',
|
34
|
-
# :action => 'new',
|
35
|
-
# :message => 'Welcome!',
|
36
|
-
# :only_path => true)
|
37
|
-
# # => "/users/new?message=Welcome%21"
|
38
|
-
#
|
39
|
-
# Notice the <tt>:only_path => true</tt> part. This is because UrlFor has no
|
40
|
-
# information about the website hostname that your Rails app is serving. So if you
|
41
|
-
# want to include the hostname as well, then you must also pass the <tt>:host</tt>
|
42
|
-
# argument:
|
43
|
-
#
|
44
|
-
# include UrlFor
|
45
|
-
# url_for(:controller => 'users',
|
46
|
-
# :action => 'new',
|
47
|
-
# :message => 'Welcome!',
|
48
|
-
# :host => 'www.example.com') # Changed this.
|
49
|
-
# # => "http://www.example.com/users/new?message=Welcome%21"
|
50
|
-
#
|
51
|
-
# By default, all controllers and views have access to a special version of url_for,
|
52
|
-
# that already knows what the current hostname is. So if you use url_for in your
|
53
|
-
# controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
|
54
|
-
# argument.
|
55
|
-
#
|
56
|
-
# For convenience reasons, mailers provide a shortcut for ActionController::UrlFor#url_for.
|
57
|
-
# So within mailers, you only have to type 'url_for' instead of 'ActionController::UrlFor#url_for'
|
58
|
-
# in full. However, mailers don't have hostname information, and what's why you'll still
|
59
|
-
# have to specify the <tt>:host</tt> argument when generating URLs in mailers.
|
60
|
-
#
|
61
|
-
#
|
62
|
-
# == URL generation for named routes
|
63
|
-
#
|
64
|
-
# UrlFor also allows one to access methods that have been auto-generated from
|
65
|
-
# named routes. For example, suppose that you have a 'users' resource in your
|
66
|
-
# <b>routes.rb</b>:
|
67
|
-
#
|
68
|
-
# map.resources :users
|
69
|
-
#
|
70
|
-
# This generates, among other things, the method <tt>users_path</tt>. By default,
|
71
|
-
# this method is accessible from your controllers, views and mailers. If you need
|
72
|
-
# to access this auto-generated method from other places (such as a model), then
|
73
|
-
# you can do that by including ActionController::UrlFor in your class:
|
74
|
-
#
|
75
|
-
# class User < ActiveRecord::Base
|
76
|
-
# include ActionController::UrlFor
|
77
|
-
#
|
78
|
-
# def base_uri
|
79
|
-
# user_path(self)
|
80
|
-
# end
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# User.find(1).base_uri # => "/users/1"
|
84
|
-
#
|
85
2
|
module UrlFor
|
86
3
|
extend ActiveSupport::Concern
|
87
4
|
|
88
|
-
|
89
|
-
ActionController::Routing::Routes.install_helpers(self)
|
90
|
-
class_attribute :default_url_options
|
91
|
-
self.default_url_options = {}
|
92
|
-
end
|
93
|
-
|
94
|
-
# Overwrite to implement a number of default options that all url_for-based methods will use. The default options should come in
|
95
|
-
# the form of a hash, just like the one you would use for url_for directly. Example:
|
96
|
-
#
|
97
|
-
# def default_url_options(options)
|
98
|
-
# { :project => @project.active? ? @project.url_name : "unknown" }
|
99
|
-
# end
|
100
|
-
#
|
101
|
-
# As you can infer from the example, this is mostly useful for situations where you want to centralize dynamic decisions about the
|
102
|
-
# urls as they stem from the business domain. Please note that any individual url_for call can always override the defaults set
|
103
|
-
# by this method.
|
104
|
-
def default_url_options(options = nil)
|
105
|
-
self.class.default_url_options
|
106
|
-
end
|
5
|
+
include ActionDispatch::Routing::UrlFor
|
107
6
|
|
108
|
-
def
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
7
|
+
def url_options
|
8
|
+
super.reverse_merge(
|
9
|
+
:host => request.host_with_port,
|
10
|
+
:protocol => request.protocol,
|
11
|
+
:_path_segments => request.symbolized_path_parameters
|
12
|
+
).merge(:script_name => request.script_name)
|
114
13
|
end
|
115
14
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
# * <tt>:only_path</tt> - If true, the relative url is returned. Defaults to +false+.
|
120
|
-
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to 'http'.
|
121
|
-
# * <tt>:host</tt> - Specifies the host the link should be targeted at.
|
122
|
-
# If <tt>:only_path</tt> is false, this option must be
|
123
|
-
# provided either explicitly, or via +default_url_options+.
|
124
|
-
# * <tt>:port</tt> - Optionally specify the port to connect to.
|
125
|
-
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
|
126
|
-
# * <tt>:skip_relative_url_root</tt> - If true, the url is not constructed using the
|
127
|
-
# +relative_url_root+ set in ActionController::Base.relative_url_root.
|
128
|
-
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
|
129
|
-
#
|
130
|
-
# Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
|
131
|
-
# +url_for+ is forwarded to the Routes module.
|
132
|
-
#
|
133
|
-
# Examples:
|
134
|
-
#
|
135
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :port=>'8080' # => 'http://somehost.org:8080/tasks/testing'
|
136
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok'
|
137
|
-
# url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/'
|
138
|
-
# url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33'
|
139
|
-
def url_for(options = {})
|
140
|
-
options ||= {}
|
141
|
-
case options
|
142
|
-
when String
|
143
|
-
options
|
144
|
-
when Hash
|
145
|
-
_url_rewriter.rewrite(rewrite_options(options))
|
146
|
-
else
|
147
|
-
polymorphic_url(options)
|
148
|
-
end
|
149
|
-
end
|
150
|
-
|
151
|
-
protected
|
152
|
-
|
153
|
-
def _url_rewriter
|
154
|
-
ActionController::UrlRewriter
|
15
|
+
def _router
|
16
|
+
raise "In order to use #url_for, you must include the helpers of a particular " \
|
17
|
+
"router. For instance, `include Rails.application.routes.url_helpers"
|
155
18
|
end
|
156
19
|
end
|
157
|
-
end
|
20
|
+
end
|