actionpack 7.2.2.1 → 8.0.5

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.
Files changed (69) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +228 -101
  3. data/README.rdoc +1 -1
  4. data/lib/abstract_controller/base.rb +1 -12
  5. data/lib/abstract_controller/collector.rb +1 -1
  6. data/lib/abstract_controller/helpers.rb +1 -1
  7. data/lib/abstract_controller/rendering.rb +0 -1
  8. data/lib/action_controller/base.rb +1 -1
  9. data/lib/action_controller/form_builder.rb +3 -3
  10. data/lib/action_controller/metal/allow_browser.rb +11 -1
  11. data/lib/action_controller/metal/conditional_get.rb +5 -1
  12. data/lib/action_controller/metal/data_streaming.rb +4 -2
  13. data/lib/action_controller/metal/instrumentation.rb +1 -2
  14. data/lib/action_controller/metal/live.rb +59 -11
  15. data/lib/action_controller/metal/params_wrapper.rb +3 -3
  16. data/lib/action_controller/metal/rate_limiting.rb +13 -4
  17. data/lib/action_controller/metal/redirecting.rb +4 -3
  18. data/lib/action_controller/metal/renderers.rb +2 -3
  19. data/lib/action_controller/metal/rendering.rb +1 -1
  20. data/lib/action_controller/metal/request_forgery_protection.rb +3 -1
  21. data/lib/action_controller/metal/streaming.rb +5 -84
  22. data/lib/action_controller/metal/strong_parameters.rb +277 -92
  23. data/lib/action_controller/railtie.rb +6 -7
  24. data/lib/action_controller/renderer.rb +0 -1
  25. data/lib/action_controller/test_case.rb +12 -2
  26. data/lib/action_dispatch/constants.rb +6 -0
  27. data/lib/action_dispatch/http/cache.rb +27 -10
  28. data/lib/action_dispatch/http/content_security_policy.rb +14 -1
  29. data/lib/action_dispatch/http/mime_negotiation.rb +8 -3
  30. data/lib/action_dispatch/http/param_builder.rb +186 -0
  31. data/lib/action_dispatch/http/param_error.rb +26 -0
  32. data/lib/action_dispatch/http/permissions_policy.rb +2 -0
  33. data/lib/action_dispatch/http/query_parser.rb +53 -0
  34. data/lib/action_dispatch/http/request.rb +64 -19
  35. data/lib/action_dispatch/http/response.rb +49 -14
  36. data/lib/action_dispatch/http/url.rb +2 -2
  37. data/lib/action_dispatch/journey/formatter.rb +8 -3
  38. data/lib/action_dispatch/journey/gtg/transition_table.rb +4 -4
  39. data/lib/action_dispatch/journey/parser.rb +99 -196
  40. data/lib/action_dispatch/journey/scanner.rb +44 -42
  41. data/lib/action_dispatch/middleware/cookies.rb +4 -2
  42. data/lib/action_dispatch/middleware/debug_exceptions.rb +19 -4
  43. data/lib/action_dispatch/middleware/debug_view.rb +0 -5
  44. data/lib/action_dispatch/middleware/exception_wrapper.rb +3 -9
  45. data/lib/action_dispatch/middleware/executor.rb +5 -2
  46. data/lib/action_dispatch/middleware/public_exceptions.rb +5 -1
  47. data/lib/action_dispatch/middleware/request_id.rb +2 -1
  48. data/lib/action_dispatch/middleware/ssl.rb +13 -3
  49. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +0 -3
  50. data/lib/action_dispatch/railtie.rb +8 -0
  51. data/lib/action_dispatch/request/session.rb +1 -0
  52. data/lib/action_dispatch/request/utils.rb +9 -3
  53. data/lib/action_dispatch/routing/inspector.rb +1 -1
  54. data/lib/action_dispatch/routing/mapper.rb +96 -67
  55. data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -2
  56. data/lib/action_dispatch/routing/route_set.rb +21 -10
  57. data/lib/action_dispatch/routing/routes_proxy.rb +1 -0
  58. data/lib/action_dispatch/system_testing/browser.rb +12 -21
  59. data/lib/action_dispatch/testing/assertion_response.rb +1 -1
  60. data/lib/action_dispatch/testing/assertions/response.rb +12 -2
  61. data/lib/action_dispatch/testing/assertions/routing.rb +16 -12
  62. data/lib/action_dispatch/testing/integration.rb +20 -10
  63. data/lib/action_dispatch/testing/request_encoder.rb +9 -9
  64. data/lib/action_dispatch/testing/test_process.rb +1 -2
  65. data/lib/action_dispatch.rb +6 -4
  66. data/lib/action_pack/gem_version.rb +4 -4
  67. metadata +16 -38
  68. data/lib/action_dispatch/journey/parser.y +0 -50
  69. data/lib/action_dispatch/journey/parser_extras.rb +0 -33
@@ -272,7 +272,7 @@ module ActionDispatch
272
272
  end
273
273
  end
274
274
 
275
- # Returns whether this request is using the standard port
275
+ # Returns whether this request is using the standard port.
276
276
  #
277
277
  # req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
278
278
  # req.standard_port? # => true
@@ -307,7 +307,7 @@ module ActionDispatch
307
307
  standard_port? ? "" : ":#{port}"
308
308
  end
309
309
 
310
- # Returns the requested port, such as 8080, based on SERVER_PORT
310
+ # Returns the requested port, such as 8080, based on SERVER_PORT.
311
311
  #
312
312
  # req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
313
313
  # req.server_port # => 80
@@ -60,8 +60,13 @@ module ActionDispatch
60
60
 
61
61
  def generate(name, options, path_parameters)
62
62
  original_options = options.dup
63
- path_params = options.delete(:path_params) || {}
64
- options = path_params.merge(options)
63
+ path_params = options.delete(:path_params)
64
+ if path_params.is_a?(Hash)
65
+ options = path_params.merge(options)
66
+ else
67
+ path_params = nil
68
+ options = options.dup
69
+ end
65
70
  constraints = path_parameters.merge(options)
66
71
  missing_keys = nil
67
72
 
@@ -79,7 +84,7 @@ module ActionDispatch
79
84
  # top-level params' normal behavior of generating query_params should be
80
85
  # preserved even if the same key is also a bind_param
81
86
  parameterized_parts.key?(key) || route.defaults.key?(key) ||
82
- (path_params.key?(key) && !original_options.key?(key))
87
+ (path_params&.key?(key) && !original_options.key?(key))
83
88
  end
84
89
 
85
90
  defaults = route.defaults
@@ -107,10 +107,10 @@ module ActionDispatch
107
107
  end
108
108
 
109
109
  {
110
- regexp_states: simple_regexp,
111
- string_states: @string_states,
112
- stdparam_states: @stdparam_states,
113
- accepting: @accepting
110
+ regexp_states: simple_regexp.stringify_keys,
111
+ string_states: @string_states.stringify_keys,
112
+ stdparam_states: @stdparam_states.stringify_keys,
113
+ accepting: @accepting.stringify_keys
114
114
  }
115
115
  end
116
116
 
@@ -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
- # :markup: markdown
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 < Racc::Parser
16
- ##### State transition tables begin ###
17
-
18
- racc_action_table = [
19
- 13, 15, 14, 7, 19, 16, 8, 19, 13, 15,
20
- 14, 7, 17, 16, 8, 13, 15, 14, 7, 21,
21
- 16, 8, 13, 15, 14, 7, 24, 16, 8 ]
22
-
23
- racc_action_check = [
24
- 2, 2, 2, 2, 22, 2, 2, 2, 19, 19,
25
- 19, 19, 1, 19, 19, 7, 7, 7, 7, 17,
26
- 7, 7, 0, 0, 0, 0, 20, 0, 0 ]
27
-
28
- racc_action_pointer = [
29
- 20, 12, -2, nil, nil, nil, nil, 13, nil, nil,
30
- nil, nil, nil, nil, nil, nil, nil, 19, nil, 6,
31
- 20, nil, -5, nil, nil ]
32
-
33
- racc_action_default = [
34
- -19, -19, -2, -3, -4, -5, -6, -19, -10, -11,
35
- -12, -13, -14, -15, -16, -17, -18, -19, -1, -19,
36
- -19, 25, -8, -9, -7 ]
37
-
38
- racc_goto_table = [
39
- 1, 22, 18, 23, nil, nil, nil, 20 ]
40
-
41
- racc_goto_check = [
42
- 1, 2, 1, 3, nil, nil, nil, 1 ]
43
-
44
- racc_goto_pointer = [
45
- nil, 0, -18, -16, nil, nil, nil, nil, nil, nil,
46
- nil ]
47
-
48
- racc_goto_default = [
49
- nil, nil, 2, 3, 4, 5, 6, 9, 10, 11,
50
- 12 ]
51
-
52
- racc_reduce_table = [
53
- 0, 0, :racc_error,
54
- 2, 11, :_reduce_1,
55
- 1, 11, :_reduce_2,
56
- 1, 11, :_reduce_none,
57
- 1, 12, :_reduce_none,
58
- 1, 12, :_reduce_none,
59
- 1, 12, :_reduce_none,
60
- 3, 15, :_reduce_7,
61
- 3, 13, :_reduce_8,
62
- 3, 13, :_reduce_9,
63
- 1, 16, :_reduce_10,
64
- 1, 14, :_reduce_none,
65
- 1, 14, :_reduce_none,
66
- 1, 14, :_reduce_none,
67
- 1, 14, :_reduce_none,
68
- 1, 19, :_reduce_15,
69
- 1, 17, :_reduce_16,
70
- 1, 18, :_reduce_17,
71
- 1, 20, :_reduce_18 ]
72
-
73
- racc_reduce_n = 19
74
-
75
- racc_shift_n = 25
76
-
77
- racc_token_table = {
78
- false => 0,
79
- :error => 1,
80
- :SLASH => 2,
81
- :LITERAL => 3,
82
- :SYMBOL => 4,
83
- :LPAREN => 5,
84
- :RPAREN => 6,
85
- :DOT => 7,
86
- :STAR => 8,
87
- :OR => 9 }
88
-
89
- racc_nt_base = 10
90
-
91
- racc_use_result_var = false
92
-
93
- Racc_arg = [
94
- racc_action_table,
95
- racc_action_check,
96
- racc_action_default,
97
- racc_action_pointer,
98
- racc_goto_table,
99
- racc_goto_check,
100
- racc_goto_default,
101
- racc_goto_pointer,
102
- racc_nt_base,
103
- racc_reduce_table,
104
- racc_token_table,
105
- racc_shift_n,
106
- racc_reduce_n,
107
- racc_use_result_var ]
108
-
109
- Racc_token_to_s_table = [
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
- @ss = nil
29
+ @scanner = nil
30
+ @length = nil
12
31
  end
13
32
 
14
33
  def scan_setup(str)
15
- @ss = StringScanner.new(str)
34
+ @scanner = Scanner.new(str)
16
35
  end
17
36
 
18
- def eos?
19
- @ss.eos?
20
- end
37
+ def next_token
38
+ return if @scanner.eos?
21
39
 
22
- def pos
23
- @ss.pos
40
+ until token = scan || @scanner.eos?; end
41
+ token
24
42
  end
25
43
 
26
- def pre_match
27
- @ss.pre_match
44
+ def last_string
45
+ -@scanner.string.byteslice(@scanner.pos - @length, @length)
28
46
  end
29
47
 
30
- def next_token
31
- return if @ss.eos?
32
-
33
- until token = scan || @ss.eos?; end
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
- when @ss.skip(/\//)
49
- [:SLASH, "/"]
50
- when @ss.skip(/\(/)
51
- [:LPAREN, "("]
52
- when @ss.skip(/\)/)
53
- [:RPAREN, ")"]
54
- when @ss.skip(/\|/)
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"
@@ -65,7 +65,9 @@ module ActionDispatch
65
65
  content_type = Mime[:text]
66
66
  end
67
67
 
68
- if api_request?(content_type)
68
+ if request.raw_request_method == "HEAD"
69
+ render(wrapper.status_code, "", content_type)
70
+ elsif api_request?(content_type)
69
71
  render_for_api_request(content_type, wrapper)
70
72
  else
71
73
  render_for_browser_request(request, wrapper)
@@ -142,17 +144,30 @@ module ActionDispatch
142
144
 
143
145
  message = []
144
146
  message << " "
145
- message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
146
147
  if wrapper.has_cause?
147
- message << "\nCauses:"
148
+ message << "#{wrapper.exception_class_name} (#{wrapper.message})"
148
149
  wrapper.wrapped_causes.each do |wrapped_cause|
149
- message << "#{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
150
+ message << "Caused by: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message})"
150
151
  end
152
+
153
+ message << "\nInformation for: #{wrapper.exception_class_name} (#{wrapper.message}):"
154
+ else
155
+ message << "#{wrapper.exception_class_name} (#{wrapper.message}):"
151
156
  end
157
+
152
158
  message.concat(wrapper.annotated_source_code)
153
159
  message << " "
154
160
  message.concat(trace)
155
161
 
162
+ if wrapper.has_cause?
163
+ wrapper.wrapped_causes.each do |wrapped_cause|
164
+ message << "\nInformation for cause: #{wrapped_cause.exception_class_name} (#{wrapped_cause.message}):"
165
+ message.concat(wrapped_cause.annotated_source_code)
166
+ message << " "
167
+ message.concat(wrapped_cause.exception_trace)
168
+ end
169
+ end
170
+
156
171
  log_array(logger, message, request)
157
172
  end
158
173
 
@@ -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")
@@ -18,8 +18,8 @@ module ActionDispatch
18
18
  "ActionController::UnknownFormat" => :not_acceptable,
19
19
  "ActionDispatch::Http::MimeNegotiation::InvalidType" => :not_acceptable,
20
20
  "ActionController::MissingExactTemplate" => :not_acceptable,
21
- "ActionController::InvalidAuthenticityToken" => :unprocessable_entity,
22
- "ActionController::InvalidCrossOriginRequest" => :unprocessable_entity,
21
+ "ActionController::InvalidAuthenticityToken" => ActionDispatch::Constants::UNPROCESSABLE_CONTENT,
22
+ "ActionController::InvalidCrossOriginRequest" => ActionDispatch::Constants::UNPROCESSABLE_CONTENT,
23
23
  "ActionDispatch::Http::Parameters::ParseError" => :bad_request,
24
24
  "ActionController::BadRequest" => :bad_request,
25
25
  "ActionController::ParameterMissing" => :bad_request,
@@ -173,7 +173,7 @@ module ActionDispatch
173
173
  end
174
174
 
175
175
  def self.status_code_for_exception(class_name)
176
- Rack::Utils.status_code(@@rescue_responses[class_name])
176
+ ActionDispatch::Response.rack_status_code(@@rescue_responses[class_name])
177
177
  end
178
178
 
179
179
  def show?(request)
@@ -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"
@@ -21,8 +21,11 @@ module ActionDispatch
21
21
  end
22
22
 
23
23
  returned = response << ::Rack::BodyProxy.new(response.pop) { state.complete! }
24
- rescue => error
25
- @executor.error_reporter.report(error, handled: false, source: "application.action_dispatch")
24
+ rescue Exception => error
25
+ request = ActionDispatch::Request.new env
26
+ backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
27
+ wrapper = ExceptionWrapper.new(backtrace_cleaner, error)
28
+ @executor.error_reporter.report(wrapper.unwrapped_exception, handled: false, source: "application.action_dispatch")
26
29
  raise
27
30
  ensure
28
31
  state.complete! unless returned
@@ -32,7 +32,11 @@ module ActionDispatch
32
32
  end
33
33
  body = { status: status, error: Rack::Utils::HTTP_STATUS_CODES.fetch(status, Rack::Utils::HTTP_STATUS_CODES[500]) }
34
34
 
35
- render(status, content_type, body)
35
+ if env["action_dispatch.original_request_method"] == "HEAD"
36
+ render_format(status, content_type, "")
37
+ else
38
+ render(status, content_type, body)
39
+ end
36
40
  end
37
41
 
38
42
  private
@@ -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.headers[@header])
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 (e.g. `redirect: {
15
- # host: "secure.widgets.com", port: 8080 }`), or set `redirect: false` to
16
- # disable this feature.
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", "&gt;= 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 %>