actionpack 7.1.3 → 7.2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +82 -501
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +15 -7
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +74 -72
- data/lib/action_controller/base.rb +198 -126
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +123 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +210 -205
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +525 -480
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +86 -60
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +10 -3
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +18 -9
- data/lib/action_dispatch/http/filter_redirect.rb +22 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +31 -24
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +20 -44
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +94 -75
- data/lib/action_dispatch/http/response.rb +73 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +8 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +671 -636
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -28
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- metadata +39 -16
@@ -1,203 +1,213 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
require "abstract_controller/collector"
|
4
6
|
|
5
7
|
module ActionController # :nodoc:
|
6
8
|
module MimeResponds
|
7
|
-
# Without web-service support, an action which collects the data for displaying
|
8
|
-
# might look something like this:
|
9
|
+
# Without web-service support, an action which collects the data for displaying
|
10
|
+
# a list of people might look something like this:
|
9
11
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
12
|
+
# def index
|
13
|
+
# @people = Person.all
|
14
|
+
# end
|
13
15
|
#
|
14
|
-
# That action implicitly responds to all formats, but formats can also be
|
16
|
+
# That action implicitly responds to all formats, but formats can also be
|
17
|
+
# explicitly enumerated:
|
15
18
|
#
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
19
|
+
# def index
|
20
|
+
# @people = Person.all
|
21
|
+
# respond_to :html, :js
|
22
|
+
# end
|
20
23
|
#
|
21
24
|
# Here's the same action, with web-service support baked in:
|
22
25
|
#
|
23
|
-
#
|
24
|
-
#
|
26
|
+
# def index
|
27
|
+
# @people = Person.all
|
25
28
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
29
|
+
# respond_to do |format|
|
30
|
+
# format.html
|
31
|
+
# format.js
|
32
|
+
# format.xml { render xml: @people }
|
33
|
+
# end
|
30
34
|
# end
|
31
|
-
# end
|
32
35
|
#
|
33
|
-
# What that says is, "if the client wants HTML or JS in response to this action,
|
34
|
-
# would have before, but if the client wants XML, return them
|
35
|
-
#
|
36
|
+
# What that says is, "if the client wants HTML or JS in response to this action,
|
37
|
+
# just respond as we would have before, but if the client wants XML, return them
|
38
|
+
# the list of people in XML format." (Rails determines the desired response
|
39
|
+
# format from the HTTP Accept header submitted by the client.)
|
36
40
|
#
|
37
|
-
# Supposing you have an action that adds a new person, optionally creating their
|
38
|
-
# (by name) if it does not already exist, without web-services, it might
|
41
|
+
# Supposing you have an action that adds a new person, optionally creating their
|
42
|
+
# company (by name) if it does not already exist, without web-services, it might
|
43
|
+
# look like this:
|
39
44
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
-
#
|
45
|
+
# def create
|
46
|
+
# @company = Company.find_or_create_by(name: params[:company][:name])
|
47
|
+
# @person = @company.people.create(params[:person])
|
43
48
|
#
|
44
|
-
#
|
45
|
-
#
|
49
|
+
# redirect_to(person_list_url)
|
50
|
+
# end
|
46
51
|
#
|
47
52
|
# Here's the same action, with web-service support baked in:
|
48
53
|
#
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
52
|
-
#
|
54
|
+
# def create
|
55
|
+
# company = params[:person].delete(:company)
|
56
|
+
# @company = Company.find_or_create_by(name: company[:name])
|
57
|
+
# @person = @company.people.create(params[:person])
|
53
58
|
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
#
|
57
|
-
#
|
59
|
+
# respond_to do |format|
|
60
|
+
# format.html { redirect_to(person_list_url) }
|
61
|
+
# format.js
|
62
|
+
# format.xml { render xml: @person.to_xml(include: @company) }
|
63
|
+
# end
|
58
64
|
# end
|
59
|
-
# end
|
60
65
|
#
|
61
|
-
# If the client wants HTML, we just redirect them back to the person list. If
|
62
|
-
# then it is an Ajax request and we render the JavaScript
|
63
|
-
#
|
64
|
-
#
|
66
|
+
# If the client wants HTML, we just redirect them back to the person list. If
|
67
|
+
# they want JavaScript, then it is an Ajax request and we render the JavaScript
|
68
|
+
# template associated with this action. Lastly, if the client wants XML, we
|
69
|
+
# render the created person as XML, but with a twist: we also include the
|
70
|
+
# person's company in the rendered XML, so you get something like this:
|
65
71
|
#
|
66
|
-
#
|
67
|
-
# <id>...</id>
|
68
|
-
# ...
|
69
|
-
# <company>
|
72
|
+
# <person>
|
70
73
|
# <id>...</id>
|
71
|
-
# <name>...</name>
|
72
74
|
# ...
|
73
|
-
#
|
74
|
-
#
|
75
|
+
# <company>
|
76
|
+
# <id>...</id>
|
77
|
+
# <name>...</name>
|
78
|
+
# ...
|
79
|
+
# </company>
|
80
|
+
# </person>
|
75
81
|
#
|
76
82
|
# Note, however, the extra bit at the top of that action:
|
77
83
|
#
|
78
|
-
#
|
79
|
-
#
|
84
|
+
# company = params[:person].delete(:company)
|
85
|
+
# @company = Company.find_or_create_by(name: company[:name])
|
80
86
|
#
|
81
|
-
# This is because the incoming XML document (if a web-service request is in
|
82
|
-
# single root-node. So, we have to rearrange things
|
87
|
+
# This is because the incoming XML document (if a web-service request is in
|
88
|
+
# process) can only contain a single root-node. So, we have to rearrange things
|
89
|
+
# so that the request looks like this (url-encoded):
|
83
90
|
#
|
84
|
-
#
|
91
|
+
# person[name]=...&person[company][name]=...&...
|
85
92
|
#
|
86
93
|
# And, like this (xml-encoded):
|
87
94
|
#
|
88
|
-
#
|
89
|
-
# <name>...</name>
|
90
|
-
# <company>
|
95
|
+
# <person>
|
91
96
|
# <name>...</name>
|
92
|
-
#
|
93
|
-
#
|
97
|
+
# <company>
|
98
|
+
# <name>...</name>
|
99
|
+
# </company>
|
100
|
+
# </person>
|
94
101
|
#
|
95
|
-
# In other words, we make the request so that it operates on a single entity's
|
96
|
-
#
|
97
|
-
# with the remaining
|
102
|
+
# In other words, we make the request so that it operates on a single entity's
|
103
|
+
# person. Then, in the action, we extract the company data from the request,
|
104
|
+
# find or create the company, and then create the new person with the remaining
|
105
|
+
# data.
|
98
106
|
#
|
99
|
-
# Note that you can define your own XML parameter parser which would allow you
|
100
|
-
# in a single request (i.e., by wrapping them all
|
101
|
-
#
|
107
|
+
# Note that you can define your own XML parameter parser which would allow you
|
108
|
+
# to describe multiple entities in a single request (i.e., by wrapping them all
|
109
|
+
# in a single root node), but if you just go with the flow and accept Rails'
|
110
|
+
# defaults, life will be much easier.
|
102
111
|
#
|
103
|
-
# If you need to use a MIME type which isn't supported by default, you can
|
104
|
-
#
|
112
|
+
# If you need to use a MIME type which isn't supported by default, you can
|
113
|
+
# register your own handlers in `config/initializers/mime_types.rb` as follows.
|
105
114
|
#
|
106
|
-
#
|
115
|
+
# Mime::Type.register "image/jpeg", :jpg
|
107
116
|
#
|
108
|
-
#
|
117
|
+
# `respond_to` also allows you to specify a common block for different formats
|
118
|
+
# by using `any`:
|
109
119
|
#
|
110
|
-
#
|
111
|
-
#
|
120
|
+
# def index
|
121
|
+
# @people = Person.all
|
112
122
|
#
|
113
|
-
#
|
114
|
-
#
|
115
|
-
#
|
123
|
+
# respond_to do |format|
|
124
|
+
# format.html
|
125
|
+
# format.any(:xml, :json) { render request.format.to_sym => @people }
|
126
|
+
# end
|
116
127
|
# end
|
117
|
-
# end
|
118
128
|
#
|
119
129
|
# In the example above, if the format is xml, it will render:
|
120
130
|
#
|
121
|
-
#
|
131
|
+
# render xml: @people
|
122
132
|
#
|
123
133
|
# Or if the format is json:
|
124
134
|
#
|
125
|
-
#
|
135
|
+
# render json: @people
|
126
136
|
#
|
127
|
-
#
|
128
|
-
# the user:
|
137
|
+
# `any` can also be used with no arguments, in which case it will be used for
|
138
|
+
# any format requested by the user:
|
129
139
|
#
|
130
|
-
#
|
131
|
-
#
|
132
|
-
#
|
133
|
-
#
|
140
|
+
# respond_to do |format|
|
141
|
+
# format.html
|
142
|
+
# format.any { redirect_to support_path }
|
143
|
+
# end
|
134
144
|
#
|
135
145
|
# Formats can have different variants.
|
136
146
|
#
|
137
|
-
# The request variant is a specialization of the request format, like
|
138
|
-
#
|
147
|
+
# The request variant is a specialization of the request format, like `:tablet`,
|
148
|
+
# `:phone`, or `:desktop`.
|
139
149
|
#
|
140
|
-
# We often want to render different html/json/xml templates for phones,
|
141
|
-
#
|
150
|
+
# We often want to render different html/json/xml templates for phones, tablets,
|
151
|
+
# and desktop browsers. Variants make it easy.
|
142
152
|
#
|
143
|
-
# You can set the variant in a
|
153
|
+
# You can set the variant in a `before_action`:
|
144
154
|
#
|
145
|
-
#
|
155
|
+
# request.variant = :tablet if /iPad/.match?(request.user_agent)
|
146
156
|
#
|
147
157
|
# Respond to variants in the action just like you respond to formats:
|
148
158
|
#
|
149
|
-
#
|
150
|
-
#
|
151
|
-
#
|
152
|
-
#
|
153
|
-
#
|
159
|
+
# respond_to do |format|
|
160
|
+
# format.html do |variant|
|
161
|
+
# variant.tablet # renders app/views/projects/show.html+tablet.erb
|
162
|
+
# variant.phone { extra_setup; render ... }
|
163
|
+
# variant.none { special_setup } # executed only if there is no variant set
|
164
|
+
# end
|
154
165
|
# end
|
155
|
-
# end
|
156
166
|
#
|
157
167
|
# Provide separate templates for each format and variant:
|
158
168
|
#
|
159
|
-
#
|
160
|
-
#
|
161
|
-
#
|
169
|
+
# app/views/projects/show.html.erb
|
170
|
+
# app/views/projects/show.html+tablet.erb
|
171
|
+
# app/views/projects/show.html+phone.erb
|
162
172
|
#
|
163
|
-
# When you're not sharing any code within the format, you can simplify defining
|
164
|
-
# using the inline syntax:
|
173
|
+
# When you're not sharing any code within the format, you can simplify defining
|
174
|
+
# variants using the inline syntax:
|
165
175
|
#
|
166
|
-
#
|
167
|
-
#
|
168
|
-
#
|
169
|
-
#
|
170
|
-
#
|
176
|
+
# respond_to do |format|
|
177
|
+
# format.js { render "trash" }
|
178
|
+
# format.html.phone { redirect_to progress_path }
|
179
|
+
# format.html.none { render "trash" }
|
180
|
+
# end
|
171
181
|
#
|
172
|
-
# Variants also support common
|
182
|
+
# Variants also support common `any`/`all` block that formats have.
|
173
183
|
#
|
174
184
|
# It works for both inline:
|
175
185
|
#
|
176
|
-
#
|
177
|
-
#
|
178
|
-
#
|
179
|
-
#
|
186
|
+
# respond_to do |format|
|
187
|
+
# format.html.any { render html: "any" }
|
188
|
+
# format.html.phone { render html: "phone" }
|
189
|
+
# end
|
180
190
|
#
|
181
191
|
# and block syntax:
|
182
192
|
#
|
183
|
-
#
|
184
|
-
#
|
185
|
-
#
|
186
|
-
#
|
193
|
+
# respond_to do |format|
|
194
|
+
# format.html do |variant|
|
195
|
+
# variant.any(:tablet, :phablet){ render html: "any" }
|
196
|
+
# variant.phone { render html: "phone" }
|
197
|
+
# end
|
187
198
|
# end
|
188
|
-
# end
|
189
199
|
#
|
190
200
|
# You can also set an array of variants:
|
191
201
|
#
|
192
|
-
#
|
202
|
+
# request.variant = [:tablet, :phone]
|
193
203
|
#
|
194
|
-
# This will work similarly to formats and MIME types negotiation. If there
|
195
|
-
#
|
204
|
+
# This will work similarly to formats and MIME types negotiation. If there is no
|
205
|
+
# `:tablet` variant declared, the `:phone` variant will be used:
|
196
206
|
#
|
197
|
-
#
|
198
|
-
#
|
199
|
-
#
|
200
|
-
#
|
207
|
+
# respond_to do |format|
|
208
|
+
# format.html.none
|
209
|
+
# format.html.phone # this gets rendered
|
210
|
+
# end
|
201
211
|
def respond_to(*mimes)
|
202
212
|
raise ArgumentError, "respond_to takes either types or a block, never both" if mimes.any? && block_given?
|
203
213
|
|
@@ -217,27 +227,26 @@ module ActionController # :nodoc:
|
|
217
227
|
end
|
218
228
|
end
|
219
229
|
|
220
|
-
# A container for responses available from the current controller for
|
221
|
-
#
|
222
|
-
#
|
223
|
-
# The public controller methods
|
224
|
-
#
|
225
|
-
#
|
226
|
-
#
|
227
|
-
#
|
228
|
-
#
|
229
|
-
#
|
230
|
-
#
|
231
|
-
#
|
232
|
-
#
|
233
|
-
#
|
234
|
-
#
|
235
|
-
#
|
236
|
-
#
|
237
|
-
#
|
238
|
-
#
|
239
|
-
#
|
240
|
-
# to determine which specific mime-type it should respond with for the current
|
230
|
+
# A container for responses available from the current controller for requests
|
231
|
+
# for different mime-types sent to a particular action.
|
232
|
+
#
|
233
|
+
# The public controller methods `respond_to` may be called with a block that is
|
234
|
+
# used to define responses to different mime-types, e.g. for `respond_to` :
|
235
|
+
#
|
236
|
+
# respond_to do |format|
|
237
|
+
# format.html
|
238
|
+
# format.xml { render xml: @people }
|
239
|
+
# end
|
240
|
+
#
|
241
|
+
# In this usage, the argument passed to the block (`format` above) is an
|
242
|
+
# instance of the ActionController::MimeResponds::Collector class. This object
|
243
|
+
# serves as a container in which available responses can be stored by calling
|
244
|
+
# any of the dynamically generated, mime-type-specific methods such as `html`,
|
245
|
+
# `xml` etc on the Collector. Each response is represented by a corresponding
|
246
|
+
# block if present.
|
247
|
+
#
|
248
|
+
# A subsequent call to #negotiate_format(request) will enable the Collector to
|
249
|
+
# determine which specific mime-type it should respond with for the current
|
241
250
|
# request, with this response then being accessible by calling #response.
|
242
251
|
class Collector
|
243
252
|
include AbstractController::Collector
|
@@ -306,7 +315,7 @@ module ActionController # :nodoc:
|
|
306
315
|
end
|
307
316
|
alias :all :any
|
308
317
|
|
309
|
-
def method_missing(name,
|
318
|
+
def method_missing(name, *, &block)
|
310
319
|
@variants[name] = block if block_given?
|
311
320
|
end
|
312
321
|
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# :markup: markdown
|
4
|
+
|
3
5
|
module ActionController
|
4
6
|
# Specify binary encoding for parameters for a given action.
|
5
7
|
module ParameterEncoding
|
@@ -21,59 +23,59 @@ module ActionController
|
|
21
23
|
end
|
22
24
|
end
|
23
25
|
|
24
|
-
# Specify that a given action's parameters should all be encoded as
|
25
|
-
#
|
26
|
+
# Specify that a given action's parameters should all be encoded as ASCII-8BIT
|
27
|
+
# (it "skips" the encoding default of UTF-8).
|
26
28
|
#
|
27
29
|
# For example, a controller would use it like this:
|
28
30
|
#
|
29
|
-
#
|
30
|
-
#
|
31
|
+
# class RepositoryController < ActionController::Base
|
32
|
+
# skip_parameter_encoding :show
|
31
33
|
#
|
32
|
-
#
|
33
|
-
#
|
34
|
+
# def show
|
35
|
+
# @repo = Repository.find_by_filesystem_path params[:file_path]
|
34
36
|
#
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
#
|
37
|
+
# # `repo_name` is guaranteed to be UTF-8, but was ASCII-8BIT, so
|
38
|
+
# # tag it as such
|
39
|
+
# @repo_name = params[:repo_name].force_encoding 'UTF-8'
|
40
|
+
# end
|
39
41
|
#
|
40
|
-
#
|
41
|
-
#
|
42
|
+
# def index
|
43
|
+
# @repositories = Repository.all
|
44
|
+
# end
|
42
45
|
# end
|
43
|
-
# end
|
44
46
|
#
|
45
47
|
# The show action in the above controller would have all parameter values
|
46
|
-
# encoded as ASCII-8BIT. This is useful in the case where an application
|
47
|
-
#
|
48
|
+
# encoded as ASCII-8BIT. This is useful in the case where an application must
|
49
|
+
# handle data but encoding of the data is unknown, like file system data.
|
48
50
|
def skip_parameter_encoding(action)
|
49
51
|
@_parameter_encodings[action.to_s] = Hash.new { Encoding::ASCII_8BIT }
|
50
52
|
end
|
51
53
|
|
52
|
-
# Specify the encoding for a parameter on an action.
|
53
|
-
#
|
54
|
+
# Specify the encoding for a parameter on an action. If not specified the
|
55
|
+
# default is UTF-8.
|
54
56
|
#
|
55
57
|
# You can specify a binary (ASCII_8BIT) parameter with:
|
56
58
|
#
|
57
|
-
#
|
58
|
-
#
|
59
|
-
#
|
59
|
+
# class RepositoryController < ActionController::Base
|
60
|
+
# # This specifies that file_path is not UTF-8 and is instead ASCII_8BIT
|
61
|
+
# param_encoding :show, :file_path, Encoding::ASCII_8BIT
|
60
62
|
#
|
61
|
-
#
|
62
|
-
#
|
63
|
+
# def show
|
64
|
+
# @repo = Repository.find_by_filesystem_path params[:file_path]
|
63
65
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
66
|
+
# # params[:repo_name] remains UTF-8 encoded
|
67
|
+
# @repo_name = params[:repo_name]
|
68
|
+
# end
|
67
69
|
#
|
68
|
-
#
|
69
|
-
#
|
70
|
+
# def index
|
71
|
+
# @repositories = Repository.all
|
72
|
+
# end
|
70
73
|
# end
|
71
|
-
# end
|
72
74
|
#
|
73
|
-
# The file_path parameter on the show action would be encoded as ASCII-8BIT,
|
74
|
-
#
|
75
|
-
#
|
76
|
-
#
|
75
|
+
# The file_path parameter on the show action would be encoded as ASCII-8BIT, but
|
76
|
+
# all other arguments will remain UTF-8 encoded. This is useful in the case
|
77
|
+
# where an application must handle data but encoding of the data is unknown,
|
78
|
+
# like file system data.
|
77
79
|
def param_encoding(action, param, encoding)
|
78
80
|
@_parameter_encodings[action.to_s][param.to_s] = encoding
|
79
81
|
end
|