actionpack 3.2.22.5 → 4.0.0.beta1
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +641 -418
- data/MIT-LICENSE +1 -1
- data/README.rdoc +5 -288
- data/lib/abstract_controller.rb +1 -8
- data/lib/abstract_controller/asset_paths.rb +2 -2
- data/lib/abstract_controller/base.rb +39 -37
- data/lib/abstract_controller/callbacks.rb +101 -82
- data/lib/abstract_controller/collector.rb +7 -3
- data/lib/abstract_controller/helpers.rb +23 -11
- data/lib/abstract_controller/layouts.rb +68 -73
- data/lib/abstract_controller/logger.rb +1 -2
- data/lib/abstract_controller/rendering.rb +22 -13
- data/lib/abstract_controller/translation.rb +16 -1
- data/lib/abstract_controller/url_for.rb +6 -6
- data/lib/abstract_controller/view_paths.rb +1 -1
- data/lib/action_controller.rb +15 -6
- data/lib/action_controller/base.rb +46 -22
- data/lib/action_controller/caching.rb +46 -33
- data/lib/action_controller/caching/fragments.rb +23 -53
- data/lib/action_controller/deprecated.rb +5 -1
- data/lib/action_controller/deprecated/integration_test.rb +3 -0
- data/lib/action_controller/log_subscriber.rb +11 -8
- data/lib/action_controller/metal.rb +16 -30
- data/lib/action_controller/metal/conditional_get.rb +76 -32
- data/lib/action_controller/metal/data_streaming.rb +20 -26
- data/lib/action_controller/metal/exceptions.rb +19 -6
- data/lib/action_controller/metal/flash.rb +24 -9
- data/lib/action_controller/metal/force_ssl.rb +32 -9
- data/lib/action_controller/metal/head.rb +25 -4
- data/lib/action_controller/metal/helpers.rb +6 -9
- data/lib/action_controller/metal/hide_actions.rb +1 -2
- data/lib/action_controller/metal/http_authentication.rb +105 -87
- data/lib/action_controller/metal/implicit_render.rb +1 -1
- data/lib/action_controller/metal/instrumentation.rb +2 -1
- data/lib/action_controller/metal/live.rb +141 -0
- data/lib/action_controller/metal/mime_responds.rb +161 -47
- data/lib/action_controller/metal/params_wrapper.rb +112 -74
- data/lib/action_controller/metal/rack_delegation.rb +9 -3
- data/lib/action_controller/metal/redirecting.rb +15 -20
- data/lib/action_controller/metal/renderers.rb +11 -9
- data/lib/action_controller/metal/rendering.rb +8 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +112 -19
- data/lib/action_controller/metal/responder.rb +20 -19
- data/lib/action_controller/metal/streaming.rb +12 -18
- data/lib/action_controller/metal/strong_parameters.rb +516 -0
- data/lib/action_controller/metal/testing.rb +13 -18
- data/lib/action_controller/metal/url_for.rb +27 -25
- data/lib/action_controller/model_naming.rb +12 -0
- data/lib/action_controller/railtie.rb +33 -17
- data/lib/action_controller/railties/helpers.rb +22 -0
- data/lib/action_controller/record_identifier.rb +18 -72
- data/lib/action_controller/test_case.rb +215 -123
- data/lib/action_controller/vendor/html-scanner.rb +4 -19
- data/lib/action_dispatch.rb +27 -19
- data/lib/action_dispatch/http/cache.rb +63 -11
- data/lib/action_dispatch/http/filter_parameters.rb +18 -8
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +27 -19
- data/lib/action_dispatch/http/mime_negotiation.rb +25 -2
- data/lib/action_dispatch/http/mime_type.rb +145 -113
- data/lib/action_dispatch/http/mime_types.rb +1 -1
- data/lib/action_dispatch/http/parameter_filter.rb +44 -46
- data/lib/action_dispatch/http/parameters.rb +12 -5
- data/lib/action_dispatch/http/rack_cache.rb +2 -3
- data/lib/action_dispatch/http/request.rb +49 -18
- data/lib/action_dispatch/http/response.rb +129 -35
- data/lib/action_dispatch/http/upload.rb +60 -17
- data/lib/action_dispatch/http/url.rb +53 -31
- data/lib/action_dispatch/journey.rb +5 -0
- data/lib/action_dispatch/journey/backwards.rb +5 -0
- data/lib/action_dispatch/journey/formatter.rb +146 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +162 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +44 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +156 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +76 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +163 -0
- data/lib/action_dispatch/journey/nodes/node.rb +124 -0
- data/lib/action_dispatch/journey/parser.rb +206 -0
- data/lib/action_dispatch/journey/parser.y +47 -0
- data/lib/action_dispatch/journey/parser_extras.rb +23 -0
- data/lib/action_dispatch/journey/path/pattern.rb +196 -0
- data/lib/action_dispatch/journey/route.rb +116 -0
- data/lib/action_dispatch/journey/router.rb +164 -0
- data/lib/action_dispatch/journey/router/strexp.rb +24 -0
- data/lib/action_dispatch/journey/router/utils.rb +54 -0
- data/lib/action_dispatch/journey/routes.rb +75 -0
- data/lib/action_dispatch/journey/scanner.rb +61 -0
- data/lib/action_dispatch/journey/visitors.rb +189 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +34 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/callbacks.rb +9 -4
- data/lib/action_dispatch/middleware/cookies.rb +168 -57
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -17
- data/lib/action_dispatch/middleware/exception_wrapper.rb +27 -3
- data/lib/action_dispatch/middleware/flash.rb +58 -58
- data/lib/action_dispatch/middleware/params_parser.rb +14 -29
- data/lib/action_dispatch/middleware/public_exceptions.rb +31 -14
- data/lib/action_dispatch/middleware/reloader.rb +6 -6
- data/lib/action_dispatch/middleware/remote_ip.rb +145 -39
- data/lib/action_dispatch/middleware/request_id.rb +2 -6
- data/lib/action_dispatch/middleware/session/abstract_store.rb +22 -20
- data/lib/action_dispatch/middleware/session/cache_store.rb +3 -3
- data/lib/action_dispatch/middleware/session/cookie_store.rb +81 -7
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +12 -45
- data/lib/action_dispatch/middleware/ssl.rb +70 -0
- data/lib/action_dispatch/middleware/stack.rb +6 -1
- data/lib/action_dispatch/middleware/static.rb +5 -24
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +14 -11
- data/lib/action_dispatch/middleware/templates/rescues/_source.erb +25 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +15 -9
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +121 -5
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +7 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +30 -15
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +39 -13
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +6 -2
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +144 -0
- data/lib/action_dispatch/railtie.rb +16 -6
- data/lib/action_dispatch/request/session.rb +181 -0
- data/lib/action_dispatch/routing.rb +41 -40
- data/lib/action_dispatch/routing/inspector.rb +240 -0
- data/lib/action_dispatch/routing/mapper.rb +501 -273
- data/lib/action_dispatch/routing/polymorphic_routes.rb +16 -20
- data/lib/action_dispatch/routing/redirection.rb +46 -29
- data/lib/action_dispatch/routing/route_set.rb +203 -164
- data/lib/action_dispatch/routing/routes_proxy.rb +2 -0
- data/lib/action_dispatch/routing/url_for.rb +48 -33
- data/lib/action_dispatch/testing/assertions/dom.rb +3 -13
- data/lib/action_dispatch/testing/assertions/response.rb +32 -40
- data/lib/action_dispatch/testing/assertions/routing.rb +40 -39
- data/lib/action_dispatch/testing/assertions/selector.rb +15 -20
- data/lib/action_dispatch/testing/assertions/tag.rb +20 -23
- data/lib/action_dispatch/testing/integration.rb +41 -22
- data/lib/action_dispatch/testing/test_process.rb +9 -6
- data/lib/action_dispatch/testing/test_request.rb +7 -3
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +4 -4
- data/lib/action_view.rb +17 -8
- data/lib/action_view/base.rb +15 -34
- data/lib/action_view/buffers.rb +1 -1
- data/lib/action_view/context.rb +4 -4
- data/lib/action_view/dependency_tracker.rb +91 -0
- data/lib/action_view/digestor.rb +85 -0
- data/lib/action_view/flows.rb +1 -4
- data/lib/action_view/helpers.rb +2 -4
- data/lib/action_view/helpers/active_model_helper.rb +3 -4
- data/lib/action_view/helpers/asset_tag_helper.rb +211 -353
- data/lib/action_view/helpers/asset_url_helper.rb +354 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +13 -10
- data/lib/action_view/helpers/cache_helper.rb +150 -18
- data/lib/action_view/helpers/capture_helper.rb +42 -29
- data/lib/action_view/helpers/csrf_helper.rb +0 -2
- data/lib/action_view/helpers/date_helper.rb +268 -247
- data/lib/action_view/helpers/debug_helper.rb +10 -11
- data/lib/action_view/helpers/form_helper.rb +904 -547
- data/lib/action_view/helpers/form_options_helper.rb +341 -166
- data/lib/action_view/helpers/form_tag_helper.rb +188 -88
- data/lib/action_view/helpers/javascript_helper.rb +23 -16
- data/lib/action_view/helpers/number_helper.rb +148 -354
- data/lib/action_view/helpers/output_safety_helper.rb +3 -3
- data/lib/action_view/helpers/record_tag_helper.rb +17 -22
- data/lib/action_view/helpers/rendering_helper.rb +2 -4
- data/lib/action_view/helpers/sanitize_helper.rb +3 -6
- data/lib/action_view/helpers/tag_helper.rb +43 -37
- data/lib/action_view/helpers/tags.rb +39 -0
- data/lib/action_view/helpers/tags/base.rb +148 -0
- data/lib/action_view/helpers/tags/check_box.rb +64 -0
- data/lib/action_view/helpers/tags/checkable.rb +16 -0
- data/lib/action_view/helpers/tags/collection_check_boxes.rb +43 -0
- data/lib/action_view/helpers/tags/collection_helpers.rb +83 -0
- data/lib/action_view/helpers/tags/collection_radio_buttons.rb +36 -0
- data/lib/action_view/helpers/tags/collection_select.rb +28 -0
- data/lib/action_view/helpers/tags/color_field.rb +25 -0
- data/lib/action_view/helpers/tags/date_field.rb +13 -0
- data/lib/action_view/helpers/tags/date_select.rb +72 -0
- data/lib/action_view/helpers/tags/datetime_field.rb +22 -0
- data/lib/action_view/helpers/tags/datetime_local_field.rb +19 -0
- data/lib/action_view/helpers/tags/datetime_select.rb +8 -0
- data/lib/action_view/helpers/tags/email_field.rb +8 -0
- data/lib/action_view/helpers/tags/file_field.rb +8 -0
- data/lib/action_view/helpers/tags/grouped_collection_select.rb +29 -0
- data/lib/action_view/helpers/tags/hidden_field.rb +8 -0
- data/lib/action_view/helpers/tags/label.rb +65 -0
- data/lib/action_view/helpers/tags/month_field.rb +13 -0
- data/lib/action_view/helpers/tags/number_field.rb +18 -0
- data/lib/action_view/helpers/tags/password_field.rb +12 -0
- data/lib/action_view/helpers/tags/radio_button.rb +31 -0
- data/lib/action_view/helpers/tags/range_field.rb +8 -0
- data/lib/action_view/helpers/tags/search_field.rb +24 -0
- data/lib/action_view/helpers/tags/select.rb +41 -0
- data/lib/action_view/helpers/tags/tel_field.rb +8 -0
- data/lib/action_view/helpers/tags/text_area.rb +18 -0
- data/lib/action_view/helpers/tags/text_field.rb +29 -0
- data/lib/action_view/helpers/tags/time_field.rb +13 -0
- data/lib/action_view/helpers/tags/time_select.rb +8 -0
- data/lib/action_view/helpers/tags/time_zone_select.rb +20 -0
- data/lib/action_view/helpers/tags/url_field.rb +8 -0
- data/lib/action_view/helpers/tags/week_field.rb +13 -0
- data/lib/action_view/helpers/text_helper.rb +126 -113
- data/lib/action_view/helpers/translation_helper.rb +32 -16
- data/lib/action_view/helpers/url_helper.rb +200 -271
- data/lib/action_view/locale/en.yml +1 -105
- data/lib/action_view/log_subscriber.rb +6 -4
- data/lib/action_view/lookup_context.rb +15 -39
- data/lib/action_view/model_naming.rb +12 -0
- data/lib/action_view/path_set.rb +9 -39
- data/lib/action_view/railtie.rb +6 -22
- data/lib/action_view/record_identifier.rb +84 -0
- data/lib/action_view/renderer/abstract_renderer.rb +10 -19
- data/lib/action_view/renderer/partial_renderer.rb +144 -81
- data/lib/action_view/renderer/renderer.rb +2 -19
- data/lib/action_view/renderer/streaming_template_renderer.rb +2 -5
- data/lib/action_view/renderer/template_renderer.rb +14 -13
- data/lib/action_view/routing_url_for.rb +107 -0
- data/lib/action_view/template.rb +22 -21
- data/lib/action_view/template/error.rb +22 -12
- data/lib/action_view/template/handlers.rb +12 -9
- data/lib/action_view/template/handlers/builder.rb +1 -1
- data/lib/action_view/template/handlers/erb.rb +11 -16
- data/lib/action_view/template/handlers/raw.rb +11 -0
- data/lib/action_view/template/resolver.rb +111 -83
- data/lib/action_view/template/text.rb +12 -8
- data/lib/action_view/template/types.rb +57 -0
- data/lib/action_view/test_case.rb +66 -43
- data/lib/action_view/testing/resolvers.rb +3 -2
- data/lib/action_view/vendor/html-scanner.rb +20 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/document.rb +0 -0
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/node.rb +12 -12
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/sanitizer.rb +18 -7
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/tokenizer.rb +1 -1
- data/lib/{action_controller → action_view}/vendor/html-scanner/html/version.rb +0 -0
- metadata +135 -125
- data/lib/action_controller/caching/actions.rb +0 -185
- data/lib/action_controller/caching/pages.rb +0 -187
- data/lib/action_controller/caching/sweeping.rb +0 -97
- data/lib/action_controller/deprecated/performance_test.rb +0 -1
- data/lib/action_controller/metal/compatibility.rb +0 -65
- data/lib/action_controller/metal/session_management.rb +0 -14
- data/lib/action_controller/railties/paths.rb +0 -25
- data/lib/action_dispatch/middleware/best_standards_support.rb +0 -30
- data/lib/action_dispatch/middleware/body_proxy.rb +0 -30
- data/lib/action_dispatch/middleware/head.rb +0 -18
- data/lib/action_dispatch/middleware/rescue.rb +0 -26
- data/lib/action_dispatch/testing/performance_test.rb +0 -10
- data/lib/action_view/asset_paths.rb +0 -142
- data/lib/action_view/helpers/asset_paths.rb +0 -7
- data/lib/action_view/helpers/asset_tag_helpers/asset_include_tag.rb +0 -146
- data/lib/action_view/helpers/asset_tag_helpers/asset_paths.rb +0 -93
- data/lib/action_view/helpers/asset_tag_helpers/javascript_tag_helpers.rb +0 -193
- data/lib/action_view/helpers/asset_tag_helpers/stylesheet_tag_helpers.rb +0 -148
- data/lib/sprockets/assets.rake +0 -99
- data/lib/sprockets/bootstrap.rb +0 -37
- data/lib/sprockets/compressors.rb +0 -83
- data/lib/sprockets/helpers.rb +0 -6
- data/lib/sprockets/helpers/isolated_helper.rb +0 -13
- data/lib/sprockets/helpers/rails_helper.rb +0 -182
- data/lib/sprockets/railtie.rb +0 -62
- data/lib/sprockets/static_compiler.rb +0 -56
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/file/path'
|
2
1
|
require 'action_controller/metal/exceptions'
|
3
2
|
|
4
3
|
module ActionController #:nodoc:
|
@@ -9,15 +8,13 @@ module ActionController #:nodoc:
|
|
9
8
|
|
10
9
|
include ActionController::Rendering
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
:disposition => 'attachment'.freeze,
|
15
|
-
}.freeze
|
11
|
+
DEFAULT_SEND_FILE_TYPE = 'application/octet-stream'.freeze #:nodoc:
|
12
|
+
DEFAULT_SEND_FILE_DISPOSITION = 'attachment'.freeze #:nodoc:
|
16
13
|
|
17
14
|
protected
|
18
15
|
# Sends the file. This uses a server-appropriate method (such as X-Sendfile)
|
19
16
|
# via the Rack::Sendfile middleware. The header to use is set via
|
20
|
-
# config.action_dispatch.x_sendfile_header
|
17
|
+
# +config.action_dispatch.x_sendfile_header+.
|
21
18
|
# Your server can also configure this for you by setting the X-Sendfile-Type header.
|
22
19
|
#
|
23
20
|
# Be careful to sanitize the path parameter if it is coming from a web
|
@@ -50,11 +47,11 @@ module ActionController #:nodoc:
|
|
50
47
|
#
|
51
48
|
# Show a JPEG in the browser:
|
52
49
|
#
|
53
|
-
# send_file '/path/to.jpeg', :
|
50
|
+
# send_file '/path/to.jpeg', type: 'image/jpeg', disposition: 'inline'
|
54
51
|
#
|
55
52
|
# Show a 404 page in the browser:
|
56
53
|
#
|
57
|
-
# send_file '/path/to/404.html', :
|
54
|
+
# send_file '/path/to/404.html', type: 'text/html; charset=utf-8', status: 404
|
58
55
|
#
|
59
56
|
# Read about the other Content-* HTTP headers if you'd like to
|
60
57
|
# provide the user with more information (such as Content-Description) in
|
@@ -99,7 +96,7 @@ module ActionController #:nodoc:
|
|
99
96
|
end
|
100
97
|
|
101
98
|
# Sends the given binary data to the browser. This method is similar to
|
102
|
-
# <tt>render :
|
99
|
+
# <tt>render text: data</tt>, but also allows you to specify whether
|
103
100
|
# the browser should display the response as a file attachment (i.e. in a
|
104
101
|
# download dialog) or as inline data. You may also set the content type,
|
105
102
|
# the apparent file name, and other things.
|
@@ -120,15 +117,15 @@ module ActionController #:nodoc:
|
|
120
117
|
#
|
121
118
|
# Download a dynamically-generated tarball:
|
122
119
|
#
|
123
|
-
# send_data generate_tgz('dir'), :
|
120
|
+
# send_data generate_tgz('dir'), filename: 'dir.tgz'
|
124
121
|
#
|
125
122
|
# Display an image Active Record in the browser:
|
126
123
|
#
|
127
|
-
# send_data image.data, :
|
124
|
+
# send_data image.data, type: image.content_type, disposition: 'inline'
|
128
125
|
#
|
129
126
|
# See +send_file+ for more information on HTTP Content-* headers and caching.
|
130
127
|
def send_data(data, options = {}) #:doc:
|
131
|
-
send_file_headers! options
|
128
|
+
send_file_headers! options
|
132
129
|
render options.slice(:status, :content_type).merge(:text => data)
|
133
130
|
end
|
134
131
|
|
@@ -136,15 +133,8 @@ module ActionController #:nodoc:
|
|
136
133
|
def send_file_headers!(options)
|
137
134
|
type_provided = options.has_key?(:type)
|
138
135
|
|
139
|
-
options.
|
140
|
-
|
141
|
-
raise ArgumentError, ":#{arg} option required" if options[arg].nil?
|
142
|
-
end
|
143
|
-
|
144
|
-
disposition = options[:disposition].to_s
|
145
|
-
disposition += %(; filename="#{options[:filename]}") if options[:filename]
|
146
|
-
|
147
|
-
content_type = options[:type]
|
136
|
+
content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
|
137
|
+
raise ArgumentError, ":type option required" if content_type.nil?
|
148
138
|
|
149
139
|
if content_type.is_a?(Symbol)
|
150
140
|
extension = Mime[content_type]
|
@@ -153,15 +143,19 @@ module ActionController #:nodoc:
|
|
153
143
|
else
|
154
144
|
if !type_provided && options[:filename]
|
155
145
|
# If type wasn't provided, try guessing from file extension.
|
156
|
-
content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.
|
146
|
+
content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete('.')) || content_type
|
157
147
|
end
|
158
148
|
self.content_type = content_type
|
159
149
|
end
|
160
150
|
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
151
|
+
disposition = options.fetch(:disposition, DEFAULT_SEND_FILE_DISPOSITION)
|
152
|
+
unless disposition.nil?
|
153
|
+
disposition = disposition.to_s
|
154
|
+
disposition += %(; filename="#{options[:filename]}") if options[:filename]
|
155
|
+
headers['Content-Disposition'] = disposition
|
156
|
+
end
|
157
|
+
|
158
|
+
headers['Content-Transfer-Encoding'] = 'binary'
|
165
159
|
|
166
160
|
response.sending_file = true
|
167
161
|
|
@@ -2,6 +2,18 @@ module ActionController
|
|
2
2
|
class ActionControllerError < StandardError #:nodoc:
|
3
3
|
end
|
4
4
|
|
5
|
+
class BadRequest < ActionControllerError #:nodoc:
|
6
|
+
attr_reader :original_exception
|
7
|
+
|
8
|
+
def initialize(type = nil, e = nil)
|
9
|
+
return super() unless type && e
|
10
|
+
|
11
|
+
super("Invalid #{type} parameters: #{e.message}")
|
12
|
+
@original_exception = e
|
13
|
+
set_backtrace e.backtrace
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
5
17
|
class RenderError < ActionControllerError #:nodoc:
|
6
18
|
end
|
7
19
|
|
@@ -13,9 +25,10 @@ module ActionController
|
|
13
25
|
end
|
14
26
|
end
|
15
27
|
|
16
|
-
class
|
17
|
-
|
28
|
+
class ActionController::UrlGenerationError < RoutingError #:nodoc:
|
29
|
+
end
|
18
30
|
|
31
|
+
class MethodNotAllowed < ActionControllerError #:nodoc:
|
19
32
|
def initialize(*allowed_methods)
|
20
33
|
super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
|
21
34
|
end
|
@@ -30,9 +43,6 @@ module ActionController
|
|
30
43
|
class MissingFile < ActionControllerError #:nodoc:
|
31
44
|
end
|
32
45
|
|
33
|
-
class RenderError < ActionControllerError #:nodoc:
|
34
|
-
end
|
35
|
-
|
36
46
|
class SessionOverflowError < ActionControllerError #:nodoc:
|
37
47
|
DEFAULT_MESSAGE = 'Your session data is larger than the data column in which it is to be stored. You must increase the size of your data column if you intend to store large data.'
|
38
48
|
|
@@ -43,4 +53,7 @@ module ActionController
|
|
43
53
|
|
44
54
|
class UnknownHttpMethod < ActionControllerError #:nodoc:
|
45
55
|
end
|
46
|
-
|
56
|
+
|
57
|
+
class UnknownFormat < ActionControllerError #:nodoc:
|
58
|
+
end
|
59
|
+
end
|
@@ -3,19 +3,34 @@ module ActionController #:nodoc:
|
|
3
3
|
extend ActiveSupport::Concern
|
4
4
|
|
5
5
|
included do
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
class_attribute :_flash_types, instance_accessor: false
|
7
|
+
self._flash_types = []
|
8
|
+
|
9
|
+
delegate :flash, to: :request
|
10
|
+
add_flash_types(:alert, :notice)
|
9
11
|
end
|
10
12
|
|
11
|
-
|
12
|
-
def
|
13
|
-
|
14
|
-
|
13
|
+
module ClassMethods
|
14
|
+
def add_flash_types(*types)
|
15
|
+
types.each do |type|
|
16
|
+
next if _flash_types.include?(type)
|
17
|
+
|
18
|
+
define_method(type) do
|
19
|
+
request.flash[type]
|
20
|
+
end
|
21
|
+
helper_method type
|
22
|
+
|
23
|
+
_flash_types << type
|
15
24
|
end
|
25
|
+
end
|
26
|
+
end
|
16
27
|
|
17
|
-
|
18
|
-
|
28
|
+
protected
|
29
|
+
def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
|
30
|
+
self.class._flash_types.each do |flash_type|
|
31
|
+
if type = response_status_and_flash.delete(flash_type)
|
32
|
+
flash[flash_type] = type
|
33
|
+
end
|
19
34
|
end
|
20
35
|
|
21
36
|
if other_flashes = response_status_and_flash.delete(:flash)
|
@@ -18,22 +18,45 @@ module ActionController
|
|
18
18
|
# Force the request to this particular controller or specified actions to be
|
19
19
|
# under HTTPS protocol.
|
20
20
|
#
|
21
|
-
#
|
21
|
+
# If you need to disable this for any reason (e.g. development) then you can use
|
22
|
+
# an +:if+ or +:unless+ condition.
|
23
|
+
#
|
24
|
+
# class AccountsController < ApplicationController
|
25
|
+
# force_ssl if: :ssl_configured?
|
26
|
+
#
|
27
|
+
# def ssl_configured?
|
28
|
+
# !Rails.env.development?
|
29
|
+
# end
|
30
|
+
# end
|
22
31
|
#
|
23
32
|
# ==== Options
|
33
|
+
# * <tt>host</tt> - Redirect to a different host name
|
24
34
|
# * <tt>only</tt> - The callback should be run only for this action
|
25
|
-
# * <tt>except</tt>
|
35
|
+
# * <tt>except</tt> - The callback should be run for all actions except this action
|
36
|
+
# * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
|
37
|
+
# will be called only when it returns a true value.
|
38
|
+
# * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
|
39
|
+
# will be called only when it returns a false value.
|
26
40
|
def force_ssl(options = {})
|
27
41
|
host = options.delete(:host)
|
28
|
-
|
29
|
-
|
30
|
-
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
|
31
|
-
redirect_options.merge!(:host => host) if host
|
32
|
-
redirect_options.merge!(:params => request.query_parameters)
|
33
|
-
redirect_to redirect_options
|
34
|
-
end
|
42
|
+
before_action(options) do
|
43
|
+
force_ssl_redirect(host)
|
35
44
|
end
|
36
45
|
end
|
37
46
|
end
|
47
|
+
|
48
|
+
# Redirect the existing request to use the HTTPS protocol.
|
49
|
+
#
|
50
|
+
# ==== Parameters
|
51
|
+
# * <tt>host</tt> - Redirect to a different host name
|
52
|
+
def force_ssl_redirect(host = nil)
|
53
|
+
unless request.ssl?
|
54
|
+
redirect_options = {:protocol => 'https://', :status => :moved_permanently}
|
55
|
+
redirect_options.merge!(:host => host) if host
|
56
|
+
redirect_options.merge!(:params => request.query_parameters)
|
57
|
+
flash.keep if respond_to?(:flash)
|
58
|
+
redirect_to redirect_options
|
59
|
+
end
|
60
|
+
end
|
38
61
|
end
|
39
62
|
end
|
@@ -7,9 +7,9 @@ module ActionController
|
|
7
7
|
# This allows you to easily return a response that consists only of
|
8
8
|
# significant headers:
|
9
9
|
#
|
10
|
-
# head :created, :
|
10
|
+
# head :created, location: person_path(@person)
|
11
11
|
#
|
12
|
-
# head :created, :
|
12
|
+
# head :created, location: @person
|
13
13
|
#
|
14
14
|
# It can also be used to return exceptional conditions:
|
15
15
|
#
|
@@ -28,8 +28,29 @@ module ActionController
|
|
28
28
|
|
29
29
|
self.status = status
|
30
30
|
self.location = url_for(location) if location
|
31
|
-
|
32
|
-
self.
|
31
|
+
|
32
|
+
if include_content?(self.status)
|
33
|
+
self.content_type = content_type || (Mime[formats.first] if formats)
|
34
|
+
self.response.charset = false if self.response
|
35
|
+
self.response_body = " "
|
36
|
+
else
|
37
|
+
headers.delete('Content-Type')
|
38
|
+
headers.delete('Content-Length')
|
39
|
+
self.response_body = ""
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
# :nodoc:
|
45
|
+
def include_content?(status)
|
46
|
+
case status
|
47
|
+
when 100..199
|
48
|
+
false
|
49
|
+
when 204, 205, 304
|
50
|
+
false
|
51
|
+
else
|
52
|
+
true
|
53
|
+
end
|
33
54
|
end
|
34
55
|
end
|
35
56
|
end
|
@@ -1,6 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/array/wrap'
|
2
|
-
require 'active_support/core_ext/class/attribute'
|
3
|
-
|
4
1
|
module ActionController
|
5
2
|
# The \Rails framework provides a large number of helpers for working with assets, dates, forms,
|
6
3
|
# numbers and model objects, to name a few. These helpers are available to all templates
|
@@ -17,7 +14,6 @@ module ActionController
|
|
17
14
|
# Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
|
18
15
|
# controller which inherits from it.
|
19
16
|
#
|
20
|
-
# ==== Examples
|
21
17
|
# The +to_s+ method from the \Time class can be wrapped in a helper method to display a custom message if
|
22
18
|
# a \Time object is blank:
|
23
19
|
#
|
@@ -53,6 +49,7 @@ module ActionController
|
|
53
49
|
module Helpers
|
54
50
|
extend ActiveSupport::Concern
|
55
51
|
|
52
|
+
class << self; attr_accessor :helpers_path; end
|
56
53
|
include AbstractController::Helpers
|
57
54
|
|
58
55
|
included do
|
@@ -93,12 +90,12 @@ module ActionController
|
|
93
90
|
end
|
94
91
|
|
95
92
|
def all_helpers_from_path(path)
|
96
|
-
helpers =
|
97
|
-
|
98
|
-
|
99
|
-
|
93
|
+
helpers = Array(path).flat_map do |_path|
|
94
|
+
extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
|
95
|
+
names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
|
96
|
+
names.sort!
|
97
|
+
names
|
100
98
|
end
|
101
|
-
helpers.sort!
|
102
99
|
helpers.uniq!
|
103
100
|
helpers
|
104
101
|
end
|
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'active_support/core_ext/class/attribute'
|
2
1
|
|
3
2
|
module ActionController
|
4
3
|
# Adds the ability to prevent public methods on a controller to be called as actions.
|
@@ -28,7 +27,7 @@ module ActionController
|
|
28
27
|
end
|
29
28
|
|
30
29
|
def visible_action?(action_name)
|
31
|
-
|
30
|
+
action_methods.include?(action_name)
|
32
31
|
end
|
33
32
|
|
34
33
|
# Overrides AbstractController::Base#action_methods to remove any methods
|
@@ -1,22 +1,21 @@
|
|
1
|
-
require '
|
2
|
-
require 'active_support/core_ext/object/blank'
|
3
|
-
require 'active_support/security_utils'
|
1
|
+
require 'base64'
|
4
2
|
|
5
3
|
module ActionController
|
4
|
+
# Makes it dead easy to do HTTP Basic, Digest and Token authentication.
|
6
5
|
module HttpAuthentication
|
7
|
-
# Makes it dead easy to do HTTP \Basic
|
6
|
+
# Makes it dead easy to do HTTP \Basic authentication.
|
8
7
|
#
|
9
8
|
# === Simple \Basic example
|
10
9
|
#
|
11
10
|
# class PostsController < ApplicationController
|
12
|
-
# http_basic_authenticate_with :
|
11
|
+
# http_basic_authenticate_with name: "dhh", password: "secret", except: :index
|
13
12
|
#
|
14
13
|
# def index
|
15
|
-
# render :
|
14
|
+
# render text: "Everyone can see me!"
|
16
15
|
# end
|
17
16
|
#
|
18
17
|
# def edit
|
19
|
-
# render :
|
18
|
+
# render text: "I'm only accessible if you know the password"
|
20
19
|
# end
|
21
20
|
# end
|
22
21
|
#
|
@@ -26,7 +25,7 @@ module ActionController
|
|
26
25
|
# the regular HTML interface is protected by a session approach:
|
27
26
|
#
|
28
27
|
# class ApplicationController < ActionController::Base
|
29
|
-
#
|
28
|
+
# before_action :set_account, :authenticate
|
30
29
|
#
|
31
30
|
# protected
|
32
31
|
# def set_account
|
@@ -61,47 +60,6 @@ module ActionController
|
|
61
60
|
#
|
62
61
|
# assert_equal 200, status
|
63
62
|
# end
|
64
|
-
#
|
65
|
-
# === Simple \Digest example
|
66
|
-
#
|
67
|
-
# require 'digest/md5'
|
68
|
-
# class PostsController < ApplicationController
|
69
|
-
# REALM = "SuperSecret"
|
70
|
-
# USERS = {"dhh" => "secret", #plain text password
|
71
|
-
# "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
72
|
-
#
|
73
|
-
# before_filter :authenticate, :except => [:index]
|
74
|
-
#
|
75
|
-
# def index
|
76
|
-
# render :text => "Everyone can see me!"
|
77
|
-
# end
|
78
|
-
#
|
79
|
-
# def edit
|
80
|
-
# render :text => "I'm only accessible if you know the password"
|
81
|
-
# end
|
82
|
-
#
|
83
|
-
# private
|
84
|
-
# def authenticate
|
85
|
-
# authenticate_or_request_with_http_digest(REALM) do |username|
|
86
|
-
# USERS[username]
|
87
|
-
# end
|
88
|
-
# end
|
89
|
-
# end
|
90
|
-
#
|
91
|
-
# === Notes
|
92
|
-
#
|
93
|
-
# The +authenticate_or_request_with_http_digest+ block must return the user's password
|
94
|
-
# or the ha1 digest hash so the framework can appropriately hash to check the user's
|
95
|
-
# credentials. Returning +nil+ will cause authentication to fail.
|
96
|
-
#
|
97
|
-
# Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
|
98
|
-
# the password file or database is compromised, the attacker would be able to use the ha1 hash to
|
99
|
-
# authenticate as the user at this +realm+, but would not have the user's password to try using at
|
100
|
-
# other sites.
|
101
|
-
#
|
102
|
-
# In rare instances, web servers or front proxies strip authorization headers before
|
103
|
-
# they reach your application. You can debug this situation by logging all environment
|
104
|
-
# variables, and check for HTTP_AUTHORIZATION, amongst others.
|
105
63
|
module Basic
|
106
64
|
extend self
|
107
65
|
|
@@ -110,13 +68,9 @@ module ActionController
|
|
110
68
|
|
111
69
|
module ClassMethods
|
112
70
|
def http_basic_authenticate_with(options = {})
|
113
|
-
|
71
|
+
before_action(options.except(:name, :password, :realm)) do
|
114
72
|
authenticate_or_request_with_http_basic(options[:realm] || "Application") do |name, password|
|
115
|
-
|
116
|
-
# uses `variable_size_secure_compare` so that length information
|
117
|
-
# isn't leaked.
|
118
|
-
ActiveSupport::SecurityUtils.variable_size_secure_compare(name, options[:name]) &
|
119
|
-
ActiveSupport::SecurityUtils.variable_size_secure_compare(password, options[:password])
|
73
|
+
name == options[:name] && password == options[:password]
|
120
74
|
end
|
121
75
|
end
|
122
76
|
end
|
@@ -160,6 +114,48 @@ module ActionController
|
|
160
114
|
end
|
161
115
|
end
|
162
116
|
|
117
|
+
# Makes it dead easy to do HTTP \Digest authentication.
|
118
|
+
#
|
119
|
+
# === Simple \Digest example
|
120
|
+
#
|
121
|
+
# require 'digest/md5'
|
122
|
+
# class PostsController < ApplicationController
|
123
|
+
# REALM = "SuperSecret"
|
124
|
+
# USERS = {"dhh" => "secret", #plain text password
|
125
|
+
# "dap" => Digest::MD5.hexdigest(["dap",REALM,"secret"].join(":"))} #ha1 digest password
|
126
|
+
#
|
127
|
+
# before_action :authenticate, except: [:index]
|
128
|
+
#
|
129
|
+
# def index
|
130
|
+
# render text: "Everyone can see me!"
|
131
|
+
# end
|
132
|
+
#
|
133
|
+
# def edit
|
134
|
+
# render text: "I'm only accessible if you know the password"
|
135
|
+
# end
|
136
|
+
#
|
137
|
+
# private
|
138
|
+
# def authenticate
|
139
|
+
# authenticate_or_request_with_http_digest(REALM) do |username|
|
140
|
+
# USERS[username]
|
141
|
+
# end
|
142
|
+
# end
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# === Notes
|
146
|
+
#
|
147
|
+
# The +authenticate_or_request_with_http_digest+ block must return the user's password
|
148
|
+
# or the ha1 digest hash so the framework can appropriately hash to check the user's
|
149
|
+
# credentials. Returning +nil+ will cause authentication to fail.
|
150
|
+
#
|
151
|
+
# Storing the ha1 hash: MD5(username:realm:password), is better than storing a plain password. If
|
152
|
+
# the password file or database is compromised, the attacker would be able to use the ha1 hash to
|
153
|
+
# authenticate as the user at this +realm+, but would not have the user's password to try using at
|
154
|
+
# other sites.
|
155
|
+
#
|
156
|
+
# In rare instances, web servers or front proxies strip authorization headers before
|
157
|
+
# they reach your application. You can debug this situation by logging all environment
|
158
|
+
# variables, and check for HTTP_AUTHORIZATION, amongst others.
|
163
159
|
module Digest
|
164
160
|
extend self
|
165
161
|
|
@@ -197,7 +193,7 @@ module ActionController
|
|
197
193
|
return false unless password
|
198
194
|
|
199
195
|
method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD']
|
200
|
-
uri = credentials[:uri]
|
196
|
+
uri = credentials[:uri]
|
201
197
|
|
202
198
|
[true, false].any? do |trailing_question_mark|
|
203
199
|
[true, false].any? do |password_is_ha1|
|
@@ -232,7 +228,7 @@ module ActionController
|
|
232
228
|
end
|
233
229
|
|
234
230
|
def decode_credentials(header)
|
235
|
-
HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/,'').split(',').map do |pair|
|
231
|
+
ActiveSupport::HashWithIndifferentAccess[header.to_s.gsub(/^Digest\s+/, '').split(',').map do |pair|
|
236
232
|
key, value = pair.split('=', 2)
|
237
233
|
[key.strip, value.to_s.gsub(/^"|"$/,'').delete('\'')]
|
238
234
|
end]
|
@@ -253,9 +249,9 @@ module ActionController
|
|
253
249
|
end
|
254
250
|
|
255
251
|
def secret_token(request)
|
256
|
-
|
257
|
-
|
258
|
-
|
252
|
+
key_generator = request.env["action_dispatch.key_generator"]
|
253
|
+
http_auth_salt = request.env["action_dispatch.http_auth_salt"]
|
254
|
+
key_generator.generate_key(http_auth_salt)
|
259
255
|
end
|
260
256
|
|
261
257
|
# Uses an MD5 digest based on time to generate a value to be used only once.
|
@@ -268,7 +264,7 @@ module ActionController
|
|
268
264
|
# The quality of the implementation depends on a good choice.
|
269
265
|
# A nonce might, for example, be constructed as the base 64 encoding of
|
270
266
|
#
|
271
|
-
#
|
267
|
+
# time-stamp H(time-stamp ":" ETag ":" private-key)
|
272
268
|
#
|
273
269
|
# where time-stamp is a server-generated time or other non-repeating value,
|
274
270
|
# ETag is the value of the HTTP ETag header associated with the requested entity,
|
@@ -284,7 +280,7 @@ module ActionController
|
|
284
280
|
#
|
285
281
|
# An implementation might choose not to accept a previously used nonce or a previously used digest, in order to
|
286
282
|
# protect against a replay attack. Or, an implementation might choose to use one-time nonces or digests for
|
287
|
-
# POST or
|
283
|
+
# POST, PUT, or PATCH requests and a time-stamp for GET requests. For more details on the issues involved see Section 4
|
288
284
|
# of this document.
|
289
285
|
#
|
290
286
|
# The nonce is opaque to the client. Composed of Time, and hash of Time with secret
|
@@ -294,11 +290,11 @@ module ActionController
|
|
294
290
|
t = time.to_i
|
295
291
|
hashed = [t, secret_key]
|
296
292
|
digest = ::Digest::MD5.hexdigest(hashed.join(":"))
|
297
|
-
::Base64.
|
293
|
+
::Base64.strict_encode64("#{t}:#{digest}")
|
298
294
|
end
|
299
295
|
|
300
296
|
# Might want a shorter timeout depending on whether the request
|
301
|
-
# is a PUT or POST, and if client is browser or web service.
|
297
|
+
# is a PATCH, PUT, or POST, and if client is browser or web service.
|
302
298
|
# Can be much shorter if the Stale directive is implemented. This would
|
303
299
|
# allow a user to use new nonce without prompting user again for their
|
304
300
|
# username and password.
|
@@ -321,14 +317,14 @@ module ActionController
|
|
321
317
|
# class PostsController < ApplicationController
|
322
318
|
# TOKEN = "secret"
|
323
319
|
#
|
324
|
-
#
|
320
|
+
# before_action :authenticate, except: [ :index ]
|
325
321
|
#
|
326
322
|
# def index
|
327
|
-
# render :
|
323
|
+
# render text: "Everyone can see me!"
|
328
324
|
# end
|
329
325
|
#
|
330
326
|
# def edit
|
331
|
-
# render :
|
327
|
+
# render text: "I'm only accessible if you know the password"
|
332
328
|
# end
|
333
329
|
#
|
334
330
|
# private
|
@@ -344,7 +340,7 @@ module ActionController
|
|
344
340
|
# the regular HTML interface is protected by a session approach:
|
345
341
|
#
|
346
342
|
# class ApplicationController < ActionController::Base
|
347
|
-
#
|
343
|
+
# before_action :set_account, :authenticate
|
348
344
|
#
|
349
345
|
# protected
|
350
346
|
# def set_account
|
@@ -375,7 +371,7 @@ module ActionController
|
|
375
371
|
# def test_access_granted_from_xml
|
376
372
|
# get(
|
377
373
|
# "/notes/1.xml", nil,
|
378
|
-
#
|
374
|
+
# 'HTTP_AUTHORIZATION' => ActionController::HttpAuthentication::Token.encode_credentials(users(:dhh).token)
|
379
375
|
# )
|
380
376
|
#
|
381
377
|
# assert_equal 200, status
|
@@ -388,6 +384,8 @@ module ActionController
|
|
388
384
|
#
|
389
385
|
# RewriteRule ^(.*)$ dispatch.fcgi [E=X-HTTP_AUTHORIZATION:%{HTTP:Authorization},QSA,L]
|
390
386
|
module Token
|
387
|
+
TOKEN_REGEX = /^Token /
|
388
|
+
AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
|
391
389
|
extend self
|
392
390
|
|
393
391
|
module ControllerMethods
|
@@ -404,16 +402,20 @@ module ActionController
|
|
404
402
|
end
|
405
403
|
end
|
406
404
|
|
407
|
-
# If token Authorization header is present, call the login
|
408
|
-
# the present token and options.
|
405
|
+
# If token Authorization header is present, call the login
|
406
|
+
# procedure with the present token and options.
|
409
407
|
#
|
410
|
-
# controller
|
411
|
-
#
|
412
|
-
# take 2 arguments:
|
413
|
-
# authenticate(controller) { |token, options| ... }
|
408
|
+
# [controller]
|
409
|
+
# ActionController::Base instance for the current request.
|
414
410
|
#
|
415
|
-
#
|
416
|
-
#
|
411
|
+
# [login_procedure]
|
412
|
+
# Proc to call if a token is present. The Proc should take two arguments:
|
413
|
+
#
|
414
|
+
# authenticate(controller) { |token, options| ... }
|
415
|
+
#
|
416
|
+
# Returns the return value of <tt>login_procedure</tt> if a
|
417
|
+
# token is found. Returns <tt>nil</tt> if no token is found.
|
418
|
+
|
417
419
|
def authenticate(controller, &login_procedure)
|
418
420
|
token, options = token_and_options(controller.request)
|
419
421
|
unless token.blank?
|
@@ -424,25 +426,41 @@ module ActionController
|
|
424
426
|
# Parses the token and options out of the token authorization header. If
|
425
427
|
# the header looks like this:
|
426
428
|
# Authorization: Token token="abc", nonce="def"
|
427
|
-
# Then the returned token is "abc", and the options is {:
|
429
|
+
# Then the returned token is "abc", and the options is {nonce: "def"}
|
428
430
|
#
|
429
431
|
# request - ActionDispatch::Request instance with the current headers.
|
430
432
|
#
|
431
433
|
# Returns an Array of [String, Hash] if a token is present.
|
432
434
|
# Returns nil if no token is found.
|
433
435
|
def token_and_options(request)
|
434
|
-
|
435
|
-
|
436
|
-
|
437
|
-
|
438
|
-
value.chomp!('"') # chomp trailing " in value
|
439
|
-
value.gsub!(/\\\"/, '"') # unescape remaining quotes
|
440
|
-
[key, value]
|
441
|
-
end]
|
442
|
-
[values.delete("token"), values.with_indifferent_access]
|
436
|
+
authorization_request = request.authorization.to_s
|
437
|
+
if authorization_request[TOKEN_REGEX]
|
438
|
+
params = token_params_from authorization_request
|
439
|
+
[params.shift.last, Hash[params].with_indifferent_access]
|
443
440
|
end
|
444
441
|
end
|
445
442
|
|
443
|
+
def token_params_from(auth)
|
444
|
+
rewrite_param_values params_array_from raw_params auth
|
445
|
+
end
|
446
|
+
|
447
|
+
# Takes raw_params and turns it into an array of parameters
|
448
|
+
def params_array_from(raw_params)
|
449
|
+
raw_params.map { |param| param.split %r/=(.+)?/ }
|
450
|
+
end
|
451
|
+
|
452
|
+
# This removes the `"` characters wrapping the value.
|
453
|
+
def rewrite_param_values(array_params)
|
454
|
+
array_params.each { |param| param.last.gsub! %r/^"|"$/, '' }
|
455
|
+
end
|
456
|
+
|
457
|
+
# This method takes an authorization body and splits up the key-value
|
458
|
+
# pairs by the standardized `:`, `;`, or `\t` delimiters defined in
|
459
|
+
# `AUTHN_PAIR_DELIMITERS`.
|
460
|
+
def raw_params(auth)
|
461
|
+
auth.sub(TOKEN_REGEX, '').split(/"\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
|
462
|
+
end
|
463
|
+
|
446
464
|
# Encodes the given token and options into an Authorization header value.
|
447
465
|
#
|
448
466
|
# token - String token.
|