actionpack 7.2.1.1 → 8.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +86 -115
- data/lib/action_controller/api.rb +1 -0
- data/lib/action_controller/metal/conditional_get.rb +6 -3
- data/lib/action_controller/metal/http_authentication.rb +6 -3
- data/lib/action_controller/metal/instrumentation.rb +1 -2
- data/lib/action_controller/metal/live.rb +19 -8
- data/lib/action_controller/metal/rate_limiting.rb +13 -4
- data/lib/action_controller/metal/renderers.rb +2 -1
- data/lib/action_controller/metal/streaming.rb +5 -84
- data/lib/action_controller/metal/strong_parameters.rb +274 -73
- data/lib/action_controller/railtie.rb +1 -1
- data/lib/action_controller/test_case.rb +4 -3
- 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/filter_parameters.rb +4 -9
- data/lib/action_dispatch/http/filter_redirect.rb +2 -9
- data/lib/action_dispatch/http/permissions_policy.rb +2 -0
- data/lib/action_dispatch/http/request.rb +4 -2
- data/lib/action_dispatch/journey/parser.rb +99 -196
- data/lib/action_dispatch/journey/scanner.rb +40 -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/remote_ip.rb +5 -6
- data/lib/action_dispatch/middleware/request_id.rb +2 -1
- data/lib/action_dispatch/middleware/ssl.rb +14 -4
- data/lib/action_dispatch/railtie.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +1 -1
- data/lib/action_dispatch/routing/mapper.rb +26 -17
- data/lib/action_dispatch/routing/route_set.rb +18 -6
- data/lib/action_dispatch/system_testing/browser.rb +12 -21
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +12 -34
- data/lib/action_dispatch/journey/parser.y +0 -50
- data/lib/action_dispatch/journey/parser_extras.rb +0 -33
@@ -37,16 +37,9 @@ module ActionDispatch
|
|
37
37
|
def parameter_filtered_location
|
38
38
|
uri = URI.parse(location)
|
39
39
|
unless uri.query.nil? || uri.query.empty?
|
40
|
-
|
41
|
-
|
42
|
-
if part.include?("=")
|
43
|
-
key, value = part.split("=", 2)
|
44
|
-
request.parameter_filter.filter(key => value).first.join("=")
|
45
|
-
else
|
46
|
-
part
|
47
|
-
end
|
40
|
+
uri.query.gsub!(FilterParameters::PAIR_RE) do
|
41
|
+
request.parameter_filter.filter($1 => $2).first.join("=")
|
48
42
|
end
|
49
|
-
uri.query = filtered_parts.join("")
|
50
43
|
end
|
51
44
|
uri.to_s
|
52
45
|
rescue URI::Error
|
@@ -86,12 +86,14 @@ module ActionDispatch # :nodoc:
|
|
86
86
|
ambient_light_sensor: "ambient-light-sensor",
|
87
87
|
autoplay: "autoplay",
|
88
88
|
camera: "camera",
|
89
|
+
display_capture: "display-capture",
|
89
90
|
encrypted_media: "encrypted-media",
|
90
91
|
fullscreen: "fullscreen",
|
91
92
|
geolocation: "geolocation",
|
92
93
|
gyroscope: "gyroscope",
|
93
94
|
hid: "hid",
|
94
95
|
idle_detection: "idle-detection",
|
96
|
+
keyboard_map: "keyboard-map",
|
95
97
|
magnetometer: "magnetometer",
|
96
98
|
microphone: "microphone",
|
97
99
|
midi: "midi",
|
@@ -55,6 +55,8 @@ module ActionDispatch
|
|
55
55
|
METHOD
|
56
56
|
end
|
57
57
|
|
58
|
+
TRANSFER_ENCODING = "HTTP_TRANSFER_ENCODING" # :nodoc:
|
59
|
+
|
58
60
|
def self.empty
|
59
61
|
new({})
|
60
62
|
end
|
@@ -282,7 +284,7 @@ module ActionDispatch
|
|
282
284
|
|
283
285
|
# Returns the content length of the request as an integer.
|
284
286
|
def content_length
|
285
|
-
return raw_post.bytesize if
|
287
|
+
return raw_post.bytesize if has_header?(TRANSFER_ENCODING)
|
286
288
|
super.to_i
|
287
289
|
end
|
288
290
|
|
@@ -468,7 +470,7 @@ module ActionDispatch
|
|
468
470
|
def read_body_stream
|
469
471
|
if body_stream
|
470
472
|
reset_stream(body_stream) do
|
471
|
-
if
|
473
|
+
if has_header?(TRANSFER_ENCODING)
|
472
474
|
body_stream.read # Read body stream until EOF if "Transfer-Encoding" is present
|
473
475
|
else
|
474
476
|
body_stream.read(content_length)
|
@@ -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,64 +7,62 @@ 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])
|
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
|
70
68
|
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
|
|
@@ -18,8 +18,8 @@ module ActionDispatch
|
|
18
18
|
# 2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2) requires.
|
19
19
|
# Some Rack servers simply drop preceding headers, and only report the value
|
20
20
|
# that was [given in the last
|
21
|
-
# header](https://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-
|
22
|
-
#
|
21
|
+
# header](https://andre.arko.net/2011/12/26/repeated-headers-and-ruby-web-servers).
|
22
|
+
# If you are behind multiple proxy servers (like NGINX to HAProxy to
|
23
23
|
# Unicorn) then you should test your Rack server to make sure your data is good.
|
24
24
|
#
|
25
25
|
# IF YOU DON'T USE A PROXY, THIS MAKES YOU VULNERABLE TO IP SPOOFING. This
|
@@ -117,10 +117,9 @@ module ActionDispatch
|
|
117
117
|
# instead, so we check that too.
|
118
118
|
#
|
119
119
|
# As discussed in [this post about Rails IP
|
120
|
-
# Spoofing](https://web.archive.org/web/20170626095448/https://blog.gingerlime.
|
121
|
-
#
|
122
|
-
#
|
123
|
-
# by the client maliciously.
|
120
|
+
# Spoofing](https://web.archive.org/web/20170626095448/https://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection/),
|
121
|
+
# while the first IP in the list is likely to be the "originating" IP, it
|
122
|
+
# could also have been set by the client maliciously.
|
124
123
|
#
|
125
124
|
# In order to find the first address that is (probably) accurate, we take the
|
126
125
|
# list of IPs, remove known and trusted proxies, and then take the last address
|
@@ -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,16 +11,26 @@ 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
|
#
|
20
|
-
# config.ssl_options = { redirect: { exclude: -> request {
|
22
|
+
# config.ssl_options = { redirect: { exclude: -> request { request.path == "/up" } } }
|
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
|
@@ -29,6 +29,7 @@ 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
|
32
33
|
|
33
34
|
config.action_dispatch.default_headers = {
|
34
35
|
"X-Frame-Options" => "SAMEORIGIN",
|
@@ -69,6 +70,7 @@ module ActionDispatch
|
|
69
70
|
|
70
71
|
ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
|
71
72
|
|
73
|
+
ActionDispatch::Http::Cache::Request.strict_freshness = app.config.action_dispatch.strict_freshness
|
72
74
|
ActionDispatch.test_app = app
|
73
75
|
end
|
74
76
|
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 = URI::
|
104
|
+
path = URI::RFC2396_PARSER.escape(filter[:grep])
|
105
105
|
normalized_path = ("/" + path).squeeze("/")
|
106
106
|
|
107
107
|
{
|