actionpack 7.2.2.1 → 8.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +123 -109
- data/lib/abstract_controller/rendering.rb +0 -1
- data/lib/action_controller/base.rb +1 -1
- data/lib/action_controller/form_builder.rb +3 -3
- data/lib/action_controller/metal/allow_browser.rb +11 -1
- data/lib/action_controller/metal/conditional_get.rb +5 -1
- data/lib/action_controller/metal/data_streaming.rb +4 -2
- data/lib/action_controller/metal/instrumentation.rb +1 -2
- data/lib/action_controller/metal/live.rb +13 -4
- data/lib/action_controller/metal/rate_limiting.rb +13 -4
- data/lib/action_controller/metal/redirecting.rb +2 -1
- data/lib/action_controller/metal/renderers.rb +2 -3
- data/lib/action_controller/metal/streaming.rb +5 -84
- data/lib/action_controller/metal/strong_parameters.rb +277 -89
- data/lib/action_controller/railtie.rb +1 -7
- data/lib/action_controller/test_case.rb +4 -2
- data/lib/action_dispatch/http/cache.rb +27 -10
- data/lib/action_dispatch/http/content_security_policy.rb +1 -0
- data/lib/action_dispatch/http/param_builder.rb +186 -0
- data/lib/action_dispatch/http/param_error.rb +26 -0
- data/lib/action_dispatch/http/permissions_policy.rb +2 -0
- data/lib/action_dispatch/http/query_parser.rb +53 -0
- data/lib/action_dispatch/http/request.rb +60 -16
- data/lib/action_dispatch/journey/parser.rb +99 -196
- data/lib/action_dispatch/journey/scanner.rb +44 -42
- data/lib/action_dispatch/middleware/cookies.rb +4 -2
- data/lib/action_dispatch/middleware/debug_exceptions.rb +16 -3
- data/lib/action_dispatch/middleware/debug_view.rb +0 -5
- data/lib/action_dispatch/middleware/exception_wrapper.rb +0 -6
- data/lib/action_dispatch/middleware/request_id.rb +2 -1
- data/lib/action_dispatch/middleware/ssl.rb +13 -3
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +0 -3
- data/lib/action_dispatch/railtie.rb +8 -0
- data/lib/action_dispatch/request/session.rb +1 -0
- data/lib/action_dispatch/request/utils.rb +9 -3
- data/lib/action_dispatch/routing/inspector.rb +1 -1
- data/lib/action_dispatch/routing/mapper.rb +90 -62
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -2
- data/lib/action_dispatch/routing/route_set.rb +20 -8
- data/lib/action_dispatch/system_testing/browser.rb +12 -21
- data/lib/action_dispatch/testing/assertions/response.rb +12 -2
- data/lib/action_dispatch/testing/assertions/routing.rb +4 -4
- data/lib/action_dispatch/testing/integration.rb +11 -1
- data/lib/action_dispatch/testing/test_process.rb +1 -2
- data/lib/action_dispatch.rb +6 -4
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +15 -34
- data/lib/action_dispatch/journey/parser.y +0 -50
- data/lib/action_dispatch/journey/parser_extras.rb +0 -33
@@ -1,200 +1,103 @@
|
|
1
|
-
#
|
2
|
-
# DO NOT MODIFY!!!!
|
3
|
-
# This file is automatically generated by Racc 1.4.16 from
|
4
|
-
# Racc grammar file "".
|
1
|
+
# frozen_string_literal: true
|
5
2
|
|
6
|
-
|
3
|
+
require "action_dispatch/journey/scanner"
|
4
|
+
require "action_dispatch/journey/nodes/node"
|
7
5
|
|
8
|
-
require 'racc/parser.rb'
|
9
|
-
|
10
|
-
# :stopdoc:
|
11
|
-
|
12
|
-
require "action_dispatch/journey/parser_extras"
|
13
6
|
module ActionDispatch
|
14
|
-
module Journey
|
15
|
-
class Parser
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
"$end",
|
111
|
-
"error",
|
112
|
-
"SLASH",
|
113
|
-
"LITERAL",
|
114
|
-
"SYMBOL",
|
115
|
-
"LPAREN",
|
116
|
-
"RPAREN",
|
117
|
-
"DOT",
|
118
|
-
"STAR",
|
119
|
-
"OR",
|
120
|
-
"$start",
|
121
|
-
"expressions",
|
122
|
-
"expression",
|
123
|
-
"or",
|
124
|
-
"terminal",
|
125
|
-
"group",
|
126
|
-
"star",
|
127
|
-
"symbol",
|
128
|
-
"literal",
|
129
|
-
"slash",
|
130
|
-
"dot" ]
|
131
|
-
|
132
|
-
Racc_debug_parser = false
|
133
|
-
|
134
|
-
##### State transition tables end #####
|
135
|
-
|
136
|
-
# reduce 0 omitted
|
137
|
-
|
138
|
-
def _reduce_1(val, _values)
|
139
|
-
Cat.new(val.first, val.last)
|
140
|
-
end
|
141
|
-
|
142
|
-
def _reduce_2(val, _values)
|
143
|
-
val.first
|
144
|
-
end
|
145
|
-
|
146
|
-
# reduce 3 omitted
|
147
|
-
|
148
|
-
# reduce 4 omitted
|
149
|
-
|
150
|
-
# reduce 5 omitted
|
151
|
-
|
152
|
-
# reduce 6 omitted
|
153
|
-
|
154
|
-
def _reduce_7(val, _values)
|
155
|
-
Group.new(val[1])
|
156
|
-
end
|
157
|
-
|
158
|
-
def _reduce_8(val, _values)
|
159
|
-
Or.new([val.first, val.last])
|
160
|
-
end
|
161
|
-
|
162
|
-
def _reduce_9(val, _values)
|
163
|
-
Or.new([val.first, val.last])
|
164
|
-
end
|
165
|
-
|
166
|
-
def _reduce_10(val, _values)
|
167
|
-
Star.new(Symbol.new(val.last, Symbol::GREEDY_EXP))
|
7
|
+
module Journey # :nodoc:
|
8
|
+
class Parser # :nodoc:
|
9
|
+
include Journey::Nodes
|
10
|
+
|
11
|
+
def self.parse(string)
|
12
|
+
new.parse string
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize
|
16
|
+
@scanner = Scanner.new
|
17
|
+
@next_token = nil
|
18
|
+
end
|
19
|
+
|
20
|
+
def parse(string)
|
21
|
+
@scanner.scan_setup(string)
|
22
|
+
advance_token
|
23
|
+
do_parse
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
def advance_token
|
28
|
+
@next_token = @scanner.next_token
|
29
|
+
end
|
30
|
+
|
31
|
+
def do_parse
|
32
|
+
parse_expressions
|
33
|
+
end
|
34
|
+
|
35
|
+
def parse_expressions
|
36
|
+
node = parse_expression
|
37
|
+
|
38
|
+
while @next_token
|
39
|
+
case @next_token
|
40
|
+
when :RPAREN
|
41
|
+
break
|
42
|
+
when :OR
|
43
|
+
node = parse_or(node)
|
44
|
+
else
|
45
|
+
node = Cat.new(node, parse_expressions)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
node
|
50
|
+
end
|
51
|
+
|
52
|
+
def parse_or(lhs)
|
53
|
+
advance_token
|
54
|
+
node = parse_expression
|
55
|
+
Or.new([lhs, node])
|
56
|
+
end
|
57
|
+
|
58
|
+
def parse_expression
|
59
|
+
if @next_token == :STAR
|
60
|
+
parse_star
|
61
|
+
elsif @next_token == :LPAREN
|
62
|
+
parse_group
|
63
|
+
else
|
64
|
+
parse_terminal
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
def parse_star
|
69
|
+
node = Star.new(Symbol.new(@scanner.last_string, Symbol::GREEDY_EXP))
|
70
|
+
advance_token
|
71
|
+
node
|
72
|
+
end
|
73
|
+
|
74
|
+
def parse_group
|
75
|
+
advance_token
|
76
|
+
node = parse_expressions
|
77
|
+
if @next_token == :RPAREN
|
78
|
+
node = Group.new(node)
|
79
|
+
advance_token
|
80
|
+
node
|
81
|
+
else
|
82
|
+
raise ArgumentError, "missing right parenthesis."
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def parse_terminal
|
87
|
+
node = case @next_token
|
88
|
+
when :SYMBOL
|
89
|
+
Symbol.new(@scanner.last_string)
|
90
|
+
when :LITERAL
|
91
|
+
Literal.new(@scanner.last_literal)
|
92
|
+
when :SLASH
|
93
|
+
Slash.new("/")
|
94
|
+
when :DOT
|
95
|
+
Dot.new(".")
|
96
|
+
end
|
97
|
+
|
98
|
+
advance_token
|
99
|
+
node
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
168
103
|
end
|
169
|
-
|
170
|
-
# reduce 11 omitted
|
171
|
-
|
172
|
-
# reduce 12 omitted
|
173
|
-
|
174
|
-
# reduce 13 omitted
|
175
|
-
|
176
|
-
# reduce 14 omitted
|
177
|
-
|
178
|
-
def _reduce_15(val, _values)
|
179
|
-
Slash.new(val.first)
|
180
|
-
end
|
181
|
-
|
182
|
-
def _reduce_16(val, _values)
|
183
|
-
Symbol.new(val.first)
|
184
|
-
end
|
185
|
-
|
186
|
-
def _reduce_17(val, _values)
|
187
|
-
Literal.new(val.first)
|
188
|
-
end
|
189
|
-
|
190
|
-
def _reduce_18(val, _values)
|
191
|
-
Dot.new(val.first)
|
192
|
-
end
|
193
|
-
|
194
|
-
def _reduce_none(val, _values)
|
195
|
-
val[0]
|
196
|
-
end
|
197
|
-
|
198
|
-
end # class Parser
|
199
|
-
end # module Journey
|
200
|
-
end # module ActionDispatch
|
@@ -7,66 +7,68 @@ require "strscan"
|
|
7
7
|
module ActionDispatch
|
8
8
|
module Journey # :nodoc:
|
9
9
|
class Scanner # :nodoc:
|
10
|
+
STATIC_TOKENS = Array.new(150)
|
11
|
+
STATIC_TOKENS[".".ord] = :DOT
|
12
|
+
STATIC_TOKENS["/".ord] = :SLASH
|
13
|
+
STATIC_TOKENS["(".ord] = :LPAREN
|
14
|
+
STATIC_TOKENS[")".ord] = :RPAREN
|
15
|
+
STATIC_TOKENS["|".ord] = :OR
|
16
|
+
STATIC_TOKENS[":".ord] = :SYMBOL
|
17
|
+
STATIC_TOKENS["*".ord] = :STAR
|
18
|
+
STATIC_TOKENS.freeze
|
19
|
+
|
20
|
+
class Scanner < StringScanner
|
21
|
+
unless method_defined?(:peek_byte) # https://github.com/ruby/strscan/pull/89
|
22
|
+
def peek_byte
|
23
|
+
string.getbyte(pos)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
10
28
|
def initialize
|
11
|
-
@
|
29
|
+
@scanner = nil
|
30
|
+
@length = nil
|
12
31
|
end
|
13
32
|
|
14
33
|
def scan_setup(str)
|
15
|
-
@
|
34
|
+
@scanner = Scanner.new(str)
|
16
35
|
end
|
17
36
|
|
18
|
-
def
|
19
|
-
@
|
20
|
-
end
|
37
|
+
def next_token
|
38
|
+
return if @scanner.eos?
|
21
39
|
|
22
|
-
|
23
|
-
|
40
|
+
until token = scan || @scanner.eos?; end
|
41
|
+
token
|
24
42
|
end
|
25
43
|
|
26
|
-
def
|
27
|
-
@
|
44
|
+
def last_string
|
45
|
+
-@scanner.string.byteslice(@scanner.pos - @length, @length)
|
28
46
|
end
|
29
47
|
|
30
|
-
def
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
token
|
48
|
+
def last_literal
|
49
|
+
last_str = @scanner.string.byteslice(@scanner.pos - @length, @length)
|
50
|
+
last_str.tr! "\\", ""
|
51
|
+
-last_str
|
35
52
|
end
|
36
53
|
|
37
54
|
private
|
38
|
-
# takes advantage of String @- deduping capabilities in Ruby 2.5 upwards see:
|
39
|
-
# https://bugs.ruby-lang.org/issues/13077
|
40
|
-
def dedup_scan(regex)
|
41
|
-
r = @ss.scan(regex)
|
42
|
-
r ? -r : nil
|
43
|
-
end
|
44
|
-
|
45
55
|
def scan
|
56
|
+
next_byte = @scanner.peek_byte
|
46
57
|
case
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
[:OR, "|"]
|
56
|
-
when @ss.skip(/\./)
|
57
|
-
[:DOT, "."]
|
58
|
-
when text = dedup_scan(/:\w+/)
|
59
|
-
[:SYMBOL, text]
|
60
|
-
when text = dedup_scan(/\*\w+/)
|
61
|
-
[:STAR, text]
|
62
|
-
when text = @ss.scan(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
|
63
|
-
text.tr! "\\", ""
|
64
|
-
[:LITERAL, -text]
|
65
|
-
# any char
|
66
|
-
when text = dedup_scan(/./)
|
67
|
-
[:LITERAL, text]
|
58
|
+
when (token = STATIC_TOKENS[next_byte]) && (token != :SYMBOL || next_byte_is_not_a_token?)
|
59
|
+
@scanner.pos += 1
|
60
|
+
@length = @scanner.skip(/\w+/).to_i + 1 if token == :SYMBOL || token == :STAR
|
61
|
+
token
|
62
|
+
when @length = @scanner.skip(/(?:[\w%\-~!$&'*+,;=@]|\\[:()])+/)
|
63
|
+
:LITERAL
|
64
|
+
when @length = @scanner.skip(/./)
|
65
|
+
:LITERAL
|
68
66
|
end
|
69
67
|
end
|
68
|
+
|
69
|
+
def next_byte_is_not_a_token?
|
70
|
+
!STATIC_TOKENS[@scanner.string.getbyte(@scanner.pos + 1)]
|
71
|
+
end
|
70
72
|
end
|
71
73
|
end
|
72
74
|
end
|
@@ -116,13 +116,15 @@ module ActionDispatch
|
|
116
116
|
# cookies[:login] = { value: "XJ-122", expires: Time.utc(2020, 10, 15, 5) }
|
117
117
|
#
|
118
118
|
# # Sets a signed cookie, which prevents users from tampering with its value.
|
119
|
-
# # It can be read using the signed method `cookies.signed[:name]`
|
120
119
|
# cookies.signed[:user_id] = current_user.id
|
120
|
+
# # It can be read using the signed method.
|
121
|
+
# cookies.signed[:user_id] # => 123
|
121
122
|
#
|
122
123
|
# # Sets an encrypted cookie value before sending it to the client which
|
123
124
|
# # prevent users from reading and tampering with its value.
|
124
|
-
# # It can be read using the encrypted method `cookies.encrypted[:name]`
|
125
125
|
# cookies.encrypted[:discount] = 45
|
126
|
+
# # It can be read using the encrypted method.
|
127
|
+
# cookies.encrypted[:discount] # => 45
|
126
128
|
#
|
127
129
|
# # Sets a "permanent" cookie (which expires in 20 years from now).
|
128
130
|
# cookies.permanent[:login] = "XJ-122"
|
@@ -142,17 +142,30 @@ module ActionDispatch
|
|
142
142
|
|
143
143
|
message = []
|
144
144
|
message << " "
|
145
|
-
message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
|
146
145
|
if wrapper.has_cause?
|
147
|
-
message << "
|
146
|
+
message << "#{wrapper.exception_class_name} (#{wrapper.message})"
|
148
147
|
wrapper.wrapped_causes.each do |wrapped_cause|
|
149
|
-
message << "#{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
|
148
|
+
message << "Caused by: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
|
150
149
|
end
|
150
|
+
|
151
|
+
message << "\nInformation for: #{wrapper.exception_class_name} (#{wrapper.message}):"
|
152
|
+
else
|
153
|
+
message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
|
151
154
|
end
|
155
|
+
|
152
156
|
message.concat(wrapper.annotated_source_code)
|
153
157
|
message << " "
|
154
158
|
message.concat(trace)
|
155
159
|
|
160
|
+
if wrapper.has_cause?
|
161
|
+
wrapper.wrapped_causes.each do |wrapped_cause|
|
162
|
+
message << "\nInformation for cause: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message}):"
|
163
|
+
message.concat(wrapped_cause.annotated_source_code)
|
164
|
+
message << " "
|
165
|
+
message.concat(wrapped_cause.exception_trace)
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
156
169
|
log_array(logger, message, request)
|
157
170
|
end
|
158
171
|
|
@@ -15,17 +15,12 @@ module ActionDispatch
|
|
15
15
|
paths = RESCUES_TEMPLATE_PATHS.dup
|
16
16
|
lookup_context = ActionView::LookupContext.new(paths)
|
17
17
|
super(lookup_context, assigns, nil)
|
18
|
-
@exception_wrapper = assigns[:exception_wrapper]
|
19
18
|
end
|
20
19
|
|
21
20
|
def compiled_method_container
|
22
21
|
self.class
|
23
22
|
end
|
24
23
|
|
25
|
-
def error_highlight_available?
|
26
|
-
@exception_wrapper.error_highlight_available?
|
27
|
-
end
|
28
|
-
|
29
24
|
def debug_params(params)
|
30
25
|
clean_params = params.clone
|
31
26
|
clean_params.delete("action")
|
@@ -201,12 +201,6 @@ module ActionDispatch
|
|
201
201
|
end
|
202
202
|
end
|
203
203
|
|
204
|
-
def error_highlight_available?
|
205
|
-
# ErrorHighlight.spot with backtrace_location keyword is available since
|
206
|
-
# error_highlight 0.4.0
|
207
|
-
defined?(ErrorHighlight) && Gem::Version.new(ErrorHighlight::VERSION) >= Gem::Version.new("0.4.0")
|
208
|
-
end
|
209
|
-
|
210
204
|
def trace_to_show
|
211
205
|
if traces["Application Trace"].empty? && rescue_template != "routing_error"
|
212
206
|
"Full Trace"
|
@@ -25,11 +25,12 @@ module ActionDispatch
|
|
25
25
|
def initialize(app, header:)
|
26
26
|
@app = app
|
27
27
|
@header = header
|
28
|
+
@env_header = "HTTP_#{header.upcase.tr("-", "_")}"
|
28
29
|
end
|
29
30
|
|
30
31
|
def call(env)
|
31
32
|
req = ActionDispatch::Request.new env
|
32
|
-
req.request_id = make_request_id(req.
|
33
|
+
req.request_id = make_request_id(req.get_header(@env_header))
|
33
34
|
@app.call(env).tap { |_status, headers, _body| headers[@header] = req.request_id }
|
34
35
|
end
|
35
36
|
|
@@ -11,9 +11,11 @@ module ActionDispatch
|
|
11
11
|
#
|
12
12
|
# 1. **TLS redirect**: Permanently redirects `http://` requests to `https://`
|
13
13
|
# with the same URL host, path, etc. Enabled by default. Set
|
14
|
-
# `config.ssl_options` to modify the destination URL
|
15
|
-
#
|
16
|
-
#
|
14
|
+
# `config.ssl_options` to modify the destination URL:
|
15
|
+
#
|
16
|
+
# config.ssl_options = { redirect: { host: "secure.widgets.com", port: 8080 }`
|
17
|
+
#
|
18
|
+
# Or set `redirect: false` to disable redirection.
|
17
19
|
#
|
18
20
|
# Requests can opt-out of redirection with `exclude`:
|
19
21
|
#
|
@@ -21,6 +23,14 @@ module ActionDispatch
|
|
21
23
|
#
|
22
24
|
# Cookies will not be flagged as secure for excluded requests.
|
23
25
|
#
|
26
|
+
# When proxying through a load balancer that terminates SSL, the forwarded
|
27
|
+
# request will appear as though it's HTTP instead of HTTPS to the application.
|
28
|
+
# This makes redirects and cookie security target HTTP instead of HTTPS.
|
29
|
+
# To make the server assume that the proxy already terminated SSL, and
|
30
|
+
# that the request really is HTTPS, set `config.assume_ssl` to `true`:
|
31
|
+
#
|
32
|
+
# config.assume_ssl = true
|
33
|
+
#
|
24
34
|
# 2. **Secure cookies**: Sets the `secure` flag on cookies to tell browsers
|
25
35
|
# they must not be sent along with `http://` requests. Enabled by default.
|
26
36
|
# Set `config.ssl_options` with `secure_cookies: false` to disable this
|
@@ -28,9 +28,6 @@
|
|
28
28
|
</tr>
|
29
29
|
</table>
|
30
30
|
</div>
|
31
|
-
<%- unless self.error_highlight_available? -%>
|
32
|
-
<p class="error_highlight_tip">Tip: You may want to add <code>gem "error_highlight", ">= 0.4.0"</code> into your Gemfile, which will display the fine-grained error location.</p>
|
33
|
-
<%- end -%>
|
34
31
|
</div>
|
35
32
|
<% end %>
|
36
33
|
<% end %>
|
@@ -29,6 +29,10 @@ module ActionDispatch
|
|
29
29
|
config.action_dispatch.request_id_header = ActionDispatch::Constants::X_REQUEST_ID
|
30
30
|
config.action_dispatch.log_rescued_responses = true
|
31
31
|
config.action_dispatch.debug_exception_log_level = :fatal
|
32
|
+
config.action_dispatch.strict_freshness = false
|
33
|
+
|
34
|
+
config.action_dispatch.ignore_leading_brackets = nil
|
35
|
+
config.action_dispatch.strict_query_string_separator = nil
|
32
36
|
|
33
37
|
config.action_dispatch.default_headers = {
|
34
38
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -51,6 +55,9 @@ module ActionDispatch
|
|
51
55
|
ActionDispatch::Http::URL.secure_protocol = app.config.force_ssl
|
52
56
|
ActionDispatch::Http::URL.tld_length = app.config.action_dispatch.tld_length
|
53
57
|
|
58
|
+
ActionDispatch::ParamBuilder.ignore_leading_brackets = app.config.action_dispatch.ignore_leading_brackets
|
59
|
+
ActionDispatch::QueryParser.strict_query_string_separator = app.config.action_dispatch.strict_query_string_separator
|
60
|
+
|
54
61
|
ActiveSupport.on_load(:action_dispatch_request) do
|
55
62
|
self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
|
56
63
|
ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
|
@@ -69,6 +76,7 @@ module ActionDispatch
|
|
69
76
|
|
70
77
|
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
|
71
78
|
|
79
|
+
ActionDispatch::Http::Cache::Request.strict_freshness = app.config.action_dispatch.strict_freshness
|
72
80
|
ActionDispatch.test_app = app
|
73
81
|
end
|
74
82
|
end
|
@@ -83,8 +83,8 @@ module ActionDispatch
|
|
83
83
|
end
|
84
84
|
|
85
85
|
class CustomParamEncoder # :nodoc:
|
86
|
-
def self.
|
87
|
-
return params unless
|
86
|
+
def self.encode_for_template(params, encoding_template)
|
87
|
+
return params unless encoding_template
|
88
88
|
params.except(:controller, :action).each do |key, value|
|
89
89
|
ActionDispatch::Request::Utils.each_param_value(value) do |param|
|
90
90
|
# If `param` is frozen, it comes from the router defaults
|
@@ -98,8 +98,14 @@ module ActionDispatch
|
|
98
98
|
params
|
99
99
|
end
|
100
100
|
|
101
|
+
def self.encode(request, params, controller, action)
|
102
|
+
encoding_template = action_encoding_template(request, controller, action)
|
103
|
+
encode_for_template(params, encoding_template)
|
104
|
+
end
|
105
|
+
|
101
106
|
def self.action_encoding_template(request, controller, action) # :nodoc:
|
102
|
-
|
107
|
+
controller && controller.valid_encoding? &&
|
108
|
+
request.controller_class_for(controller).action_encoding_template(action)
|
103
109
|
rescue MissingController
|
104
110
|
nil
|
105
111
|
end
|
@@ -101,7 +101,7 @@ module ActionDispatch
|
|
101
101
|
{ controller: /#{filter[:controller].underscore.sub(/_?controller\z/, "")}/ }
|
102
102
|
elsif filter[:grep]
|
103
103
|
grep_pattern = Regexp.new(filter[:grep])
|
104
|
-
path = RFC2396_PARSER.escape(filter[:grep])
|
104
|
+
path = URI::RFC2396_PARSER.escape(filter[:grep])
|
105
105
|
normalized_path = ("/" + path).squeeze("/")
|
106
106
|
|
107
107
|
{
|