actionpack 4.2.11.1 → 6.0.3

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.

Files changed (182) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +212 -526
  3. data/MIT-LICENSE +1 -1
  4. data/README.rdoc +9 -9
  5. data/lib/abstract_controller/asset_paths.rb +2 -0
  6. data/lib/abstract_controller/base.rb +47 -50
  7. data/lib/{action_controller → abstract_controller}/caching/fragments.rb +64 -17
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/callbacks.rb +59 -31
  10. data/lib/abstract_controller/collector.rb +9 -13
  11. data/lib/abstract_controller/error.rb +6 -0
  12. data/lib/abstract_controller/helpers.rb +31 -30
  13. data/lib/abstract_controller/logger.rb +2 -0
  14. data/lib/abstract_controller/railties/routes_helpers.rb +5 -3
  15. data/lib/abstract_controller/rendering.rb +42 -41
  16. data/lib/abstract_controller/translation.rb +12 -9
  17. data/lib/abstract_controller/url_for.rb +2 -0
  18. data/lib/abstract_controller.rb +12 -5
  19. data/lib/action_controller/api/api_rendering.rb +16 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/base.rb +25 -22
  22. data/lib/action_controller/caching.rb +13 -57
  23. data/lib/action_controller/form_builder.rb +50 -0
  24. data/lib/action_controller/log_subscriber.rb +15 -17
  25. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  26. data/lib/action_controller/metal/conditional_get.rb +124 -44
  27. data/lib/action_controller/metal/content_security_policy.rb +51 -0
  28. data/lib/action_controller/metal/cookies.rb +3 -3
  29. data/lib/action_controller/metal/data_streaming.rb +29 -49
  30. data/lib/action_controller/metal/default_headers.rb +17 -0
  31. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  32. data/lib/action_controller/metal/etag_with_template_digest.rb +20 -13
  33. data/lib/action_controller/metal/exceptions.rb +30 -15
  34. data/lib/action_controller/metal/flash.rb +9 -8
  35. data/lib/action_controller/metal/force_ssl.rb +23 -62
  36. data/lib/action_controller/metal/head.rb +22 -20
  37. data/lib/action_controller/metal/helpers.rb +26 -17
  38. data/lib/action_controller/metal/http_authentication.rb +76 -70
  39. data/lib/action_controller/metal/implicit_render.rb +53 -9
  40. data/lib/action_controller/metal/instrumentation.rb +22 -27
  41. data/lib/action_controller/metal/live.rb +101 -119
  42. data/lib/action_controller/metal/mime_responds.rb +44 -46
  43. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  44. data/lib/action_controller/metal/params_wrapper.rb +74 -63
  45. data/lib/action_controller/metal/redirecting.rb +53 -32
  46. data/lib/action_controller/metal/renderers.rb +87 -44
  47. data/lib/action_controller/metal/rendering.rb +72 -51
  48. data/lib/action_controller/metal/request_forgery_protection.rb +217 -97
  49. data/lib/action_controller/metal/rescue.rb +9 -16
  50. data/lib/action_controller/metal/streaming.rb +12 -11
  51. data/lib/action_controller/metal/strong_parameters.rb +619 -183
  52. data/lib/action_controller/metal/testing.rb +2 -17
  53. data/lib/action_controller/metal/url_for.rb +19 -10
  54. data/lib/action_controller/metal.rb +104 -87
  55. data/lib/action_controller/railtie.rb +28 -10
  56. data/lib/action_controller/railties/helpers.rb +3 -1
  57. data/lib/action_controller/renderer.rb +130 -0
  58. data/lib/action_controller/template_assertions.rb +11 -0
  59. data/lib/action_controller/test_case.rb +286 -418
  60. data/lib/action_controller.rb +33 -21
  61. data/lib/action_dispatch/http/cache.rb +100 -51
  62. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  63. data/lib/action_dispatch/http/content_security_policy.rb +282 -0
  64. data/lib/action_dispatch/http/filter_parameters.rb +31 -24
  65. data/lib/action_dispatch/http/filter_redirect.rb +10 -12
  66. data/lib/action_dispatch/http/headers.rb +54 -22
  67. data/lib/action_dispatch/http/mime_negotiation.rb +61 -45
  68. data/lib/action_dispatch/http/mime_type.rb +141 -122
  69. data/lib/action_dispatch/http/mime_types.rb +20 -6
  70. data/lib/action_dispatch/http/parameter_filter.rb +8 -68
  71. data/lib/action_dispatch/http/parameters.rb +107 -39
  72. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  73. data/lib/action_dispatch/http/request.rb +204 -117
  74. data/lib/action_dispatch/http/response.rb +248 -114
  75. data/lib/action_dispatch/http/upload.rb +21 -7
  76. data/lib/action_dispatch/http/url.rb +181 -100
  77. data/lib/action_dispatch/journey/formatter.rb +56 -34
  78. data/lib/action_dispatch/journey/gtg/builder.rb +7 -6
  79. data/lib/action_dispatch/journey/gtg/simulator.rb +3 -9
  80. data/lib/action_dispatch/journey/gtg/transition_table.rb +17 -17
  81. data/lib/action_dispatch/journey/nfa/builder.rb +5 -3
  82. data/lib/action_dispatch/journey/nfa/dot.rb +13 -13
  83. data/lib/action_dispatch/journey/nfa/simulator.rb +3 -3
  84. data/lib/action_dispatch/journey/nfa/transition_table.rb +5 -49
  85. data/lib/action_dispatch/journey/nodes/node.rb +25 -12
  86. data/lib/action_dispatch/journey/parser.rb +23 -22
  87. data/lib/action_dispatch/journey/parser.y +3 -2
  88. data/lib/action_dispatch/journey/parser_extras.rb +12 -4
  89. data/lib/action_dispatch/journey/path/pattern.rb +55 -46
  90. data/lib/action_dispatch/journey/route.rb +107 -28
  91. data/lib/action_dispatch/journey/router/utils.rb +25 -16
  92. data/lib/action_dispatch/journey/router.rb +35 -27
  93. data/lib/action_dispatch/journey/routes.rb +17 -17
  94. data/lib/action_dispatch/journey/scanner.rb +26 -17
  95. data/lib/action_dispatch/journey/visitors.rb +98 -54
  96. data/lib/action_dispatch/journey.rb +7 -5
  97. data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
  98. data/lib/action_dispatch/middleware/callbacks.rb +3 -6
  99. data/lib/action_dispatch/middleware/cookies.rb +292 -203
  100. data/lib/action_dispatch/middleware/debug_exceptions.rb +142 -63
  101. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  102. data/lib/action_dispatch/middleware/debug_view.rb +66 -0
  103. data/lib/action_dispatch/middleware/exception_wrapper.rb +102 -70
  104. data/lib/action_dispatch/middleware/executor.rb +21 -0
  105. data/lib/action_dispatch/middleware/flash.rb +78 -54
  106. data/lib/action_dispatch/middleware/host_authorization.rb +101 -0
  107. data/lib/action_dispatch/middleware/public_exceptions.rb +32 -27
  108. data/lib/action_dispatch/middleware/reloader.rb +5 -91
  109. data/lib/action_dispatch/middleware/remote_ip.rb +48 -41
  110. data/lib/action_dispatch/middleware/request_id.rb +17 -9
  111. data/lib/action_dispatch/middleware/session/abstract_store.rb +41 -26
  112. data/lib/action_dispatch/middleware/session/cache_store.rb +24 -14
  113. data/lib/action_dispatch/middleware/session/cookie_store.rb +72 -73
  114. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +8 -2
  115. data/lib/action_dispatch/middleware/show_exceptions.rb +26 -23
  116. data/lib/action_dispatch/middleware/ssl.rb +113 -35
  117. data/lib/action_dispatch/middleware/stack.rb +64 -41
  118. data/lib/action_dispatch/middleware/static.rb +57 -51
  119. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  120. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  121. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -14
  122. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
  123. data/lib/action_dispatch/middleware/templates/rescues/{_source.erb → _source.html.erb} +4 -2
  124. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
  126. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
  129. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
  130. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +5 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
  136. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
  137. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
  138. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +1 -1
  139. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +4 -4
  140. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +67 -64
  141. data/lib/action_dispatch/railtie.rb +26 -13
  142. data/lib/action_dispatch/request/session.rb +114 -60
  143. data/lib/action_dispatch/request/utils.rb +67 -24
  144. data/lib/action_dispatch/routing/endpoint.rb +9 -2
  145. data/lib/action_dispatch/routing/inspector.rb +140 -102
  146. data/lib/action_dispatch/routing/mapper.rb +762 -455
  147. data/lib/action_dispatch/routing/polymorphic_routes.rb +161 -142
  148. data/lib/action_dispatch/routing/redirection.rb +36 -26
  149. data/lib/action_dispatch/routing/route_set.rb +322 -298
  150. data/lib/action_dispatch/routing/routes_proxy.rb +32 -5
  151. data/lib/action_dispatch/routing/url_for.rb +65 -26
  152. data/lib/action_dispatch/routing.rb +36 -36
  153. data/lib/action_dispatch/system_test_case.rb +185 -0
  154. data/lib/action_dispatch/system_testing/browser.rb +80 -0
  155. data/lib/action_dispatch/system_testing/driver.rb +68 -0
  156. data/lib/action_dispatch/system_testing/server.rb +31 -0
  157. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +97 -0
  158. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +32 -0
  159. data/lib/action_dispatch/testing/assertion_response.rb +46 -0
  160. data/lib/action_dispatch/testing/assertions/response.rb +44 -20
  161. data/lib/action_dispatch/testing/assertions/routing.rb +44 -28
  162. data/lib/action_dispatch/testing/assertions.rb +6 -4
  163. data/lib/action_dispatch/testing/integration.rb +375 -215
  164. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  165. data/lib/action_dispatch/testing/test_process.rb +28 -22
  166. data/lib/action_dispatch/testing/test_request.rb +27 -34
  167. data/lib/action_dispatch/testing/test_response.rb +11 -11
  168. data/lib/action_dispatch.rb +33 -20
  169. data/lib/action_pack/gem_version.rb +6 -4
  170. data/lib/action_pack/version.rb +3 -1
  171. data/lib/action_pack.rb +4 -2
  172. metadata +71 -40
  173. data/lib/action_controller/metal/hide_actions.rb +0 -40
  174. data/lib/action_controller/metal/rack_delegation.rb +0 -32
  175. data/lib/action_controller/middleware.rb +0 -39
  176. data/lib/action_controller/model_naming.rb +0 -12
  177. data/lib/action_dispatch/journey/backwards.rb +0 -5
  178. data/lib/action_dispatch/journey/router/strexp.rb +0 -27
  179. data/lib/action_dispatch/middleware/params_parser.rb +0 -60
  180. data/lib/action_dispatch/testing/assertions/dom.rb +0 -3
  181. data/lib/action_dispatch/testing/assertions/selector.rb +0 -3
  182. data/lib/action_dispatch/testing/assertions/tag.rb +0 -3
@@ -1,4 +1,7 @@
1
- require 'action_controller/metal/exceptions'
1
+ # frozen_string_literal: true
2
+
3
+ require "action_controller/metal/exceptions"
4
+ require "action_dispatch/http/content_disposition"
2
5
 
3
6
  module ActionController #:nodoc:
4
7
  # Methods for sending arbitrary data and for streaming files to the browser,
@@ -8,10 +11,10 @@ module ActionController #:nodoc:
8
11
 
9
12
  include ActionController::Rendering
10
13
 
11
- DEFAULT_SEND_FILE_TYPE = 'application/octet-stream'.freeze #:nodoc:
12
- DEFAULT_SEND_FILE_DISPOSITION = 'attachment'.freeze #:nodoc:
14
+ DEFAULT_SEND_FILE_TYPE = "application/octet-stream" #:nodoc:
15
+ DEFAULT_SEND_FILE_DISPOSITION = "attachment" #:nodoc:
13
16
 
14
- protected
17
+ private
15
18
  # Sends the file. This uses a server-appropriate method (such as X-Sendfile)
16
19
  # via the Rack::Sendfile middleware. The header to use is set via
17
20
  # +config.action_dispatch.x_sendfile_header+.
@@ -25,14 +28,13 @@ module ActionController #:nodoc:
25
28
  # * <tt>:filename</tt> - suggests a filename for the browser to use.
26
29
  # Defaults to <tt>File.basename(path)</tt>.
27
30
  # * <tt>:type</tt> - specifies an HTTP content type.
28
- # You can specify either a string or a symbol for a registered type register with
29
- # <tt>Mime::Type.register</tt>, for example :json
30
- # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
31
- # If no content type is registered for the extension, default type 'application/octet-stream' will be used.
31
+ # You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json.
32
+ # If omitted, the type will be inferred from the file extension specified in <tt>:filename</tt>.
33
+ # If no content type is registered for the extension, the default type 'application/octet-stream' will be used.
32
34
  # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
33
35
  # Valid values are 'inline' and 'attachment' (default).
34
36
  # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
35
- # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser guess the filename from
37
+ # * <tt>:url_based_filename</tt> - set to +true+ if you want the browser to guess the filename from
36
38
  # the URL, which is necessary for i18n filenames on certain browsers
37
39
  # (setting <tt>:filename</tt> overrides this option).
38
40
  #
@@ -55,58 +57,38 @@ module ActionController #:nodoc:
55
57
  #
56
58
  # Read about the other Content-* HTTP headers if you'd like to
57
59
  # provide the user with more information (such as Content-Description) in
58
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
60
+ # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.11.
59
61
  #
60
62
  # Also be aware that the document may be cached by proxies and browsers.
61
63
  # The Pragma and Cache-Control headers declare how the file may be cached
62
64
  # by intermediaries. They default to require clients to validate with
63
65
  # the server before releasing cached responses. See
64
- # http://www.mnot.net/cache_docs/ for an overview of web caching and
65
- # http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
66
+ # https://www.mnot.net/cache_docs/ for an overview of web caching and
67
+ # https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9
66
68
  # for the Cache-Control header spec.
67
69
  def send_file(path, options = {}) #:doc:
68
- raise MissingFile, "Cannot read file #{path}" unless File.file?(path) and File.readable?(path)
70
+ raise MissingFile, "Cannot read file #{path}" unless File.file?(path) && File.readable?(path)
69
71
 
70
72
  options[:filename] ||= File.basename(path) unless options[:url_based_filename]
71
73
  send_file_headers! options
72
74
 
73
75
  self.status = options[:status] || 200
74
76
  self.content_type = options[:content_type] if options.key?(:content_type)
75
- self.response_body = FileBody.new(path)
76
- end
77
-
78
- # Avoid having to pass an open file handle as the response body.
79
- # Rack::Sendfile will usually intercept the response and uses
80
- # the path directly, so there is no reason to open the file.
81
- class FileBody #:nodoc:
82
- attr_reader :to_path
83
-
84
- def initialize(path)
85
- @to_path = path
86
- end
87
-
88
- # Stream the file's contents if Rack::Sendfile isn't present.
89
- def each
90
- File.open(to_path, 'rb') do |file|
91
- while chunk = file.read(16384)
92
- yield chunk
93
- end
94
- end
95
- end
77
+ response.send_file path
96
78
  end
97
79
 
98
80
  # Sends the given binary data to the browser. This method is similar to
99
81
  # <tt>render plain: data</tt>, but also allows you to specify whether
100
82
  # the browser should display the response as a file attachment (i.e. in a
101
83
  # download dialog) or as inline data. You may also set the content type,
102
- # the apparent file name, and other things.
84
+ # the file name, and other things.
103
85
  #
104
86
  # Options:
105
87
  # * <tt>:filename</tt> - suggests a filename for the browser to use.
106
- # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'. You can specify
107
- # either a string or a symbol for a registered type register with <tt>Mime::Type.register</tt>, for example :json
108
- # If omitted, type will be guessed from the file extension specified in <tt>:filename</tt>.
109
- # If no content type is registered for the extension, default type 'application/octet-stream' will be used.
88
+ # * <tt>:type</tt> - specifies an HTTP content type. Defaults to 'application/octet-stream'.
89
+ # You can specify either a string or a symbol for a registered type with <tt>Mime::Type.register</tt>, for example :json.
90
+ # If omitted, type will be inferred from the file extension specified in <tt>:filename</tt>.
91
+ # If no content type is registered for the extension, the default type 'application/octet-stream' will be used.
110
92
  # * <tt>:disposition</tt> - specifies whether the file will be shown inline or downloaded.
111
93
  # Valid values are 'inline' and 'attachment' (default).
112
94
  # * <tt>:status</tt> - specifies the status code to send with the response. Defaults to 200.
@@ -126,14 +108,16 @@ module ActionController #:nodoc:
126
108
  # See +send_file+ for more information on HTTP Content-* headers and caching.
127
109
  def send_data(data, options = {}) #:doc:
128
110
  send_file_headers! options
129
- render options.slice(:status, :content_type).merge(:text => data)
111
+ render options.slice(:status, :content_type).merge(body: data)
130
112
  end
131
113
 
132
- private
133
114
  def send_file_headers!(options)
134
115
  type_provided = options.has_key?(:type)
135
116
 
136
117
  content_type = options.fetch(:type, DEFAULT_SEND_FILE_TYPE)
118
+ self.content_type = content_type
119
+ response.sending_file = true
120
+
137
121
  raise ArgumentError, ":type option required" if content_type.nil?
138
122
 
139
123
  if content_type.is_a?(Symbol)
@@ -143,21 +127,17 @@ module ActionController #:nodoc:
143
127
  else
144
128
  if !type_provided && options[:filename]
145
129
  # If type wasn't provided, try guessing from file extension.
146
- content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete('.')) || content_type
130
+ content_type = Mime::Type.lookup_by_extension(File.extname(options[:filename]).downcase.delete(".")) || content_type
147
131
  end
148
132
  self.content_type = content_type
149
133
  end
150
134
 
151
135
  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
136
+ if disposition
137
+ headers["Content-Disposition"] = ActionDispatch::Http::ContentDisposition.format(disposition: disposition, filename: options[:filename])
156
138
  end
157
139
 
158
- headers['Content-Transfer-Encoding'] = 'binary'
159
-
160
- response.sending_file = true
140
+ headers["Content-Transfer-Encoding"] = "binary"
161
141
 
162
142
  # Fix a problem with IE 6.0 on opening downloaded files:
163
143
  # If Cache-Control: no-cache is set (which Rails does by default),
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # Allows configuring default headers that will be automatically merged into
5
+ # each response.
6
+ module DefaultHeaders
7
+ extend ActiveSupport::Concern
8
+
9
+ module ClassMethods
10
+ def make_response!(request)
11
+ ActionDispatch::Response.create.tap do |res|
12
+ res.request = request
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionController
4
+ # When you're using the flash, it's generally used as a conditional on the view.
5
+ # This means the content of the view depends on the flash. Which in turn means
6
+ # that the ETag for a response should be computed with the content of the flash
7
+ # in mind. This does that by including the content of the flash as a component
8
+ # in the ETag that's generated for a response.
9
+ module EtagWithFlash
10
+ extend ActiveSupport::Concern
11
+
12
+ include ActionController::ConditionalGet
13
+
14
+ included do
15
+ etag { flash unless flash.empty? }
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # When our views change, they should bubble up into HTTP cache freshness
3
5
  # and bust browser caches. So the template digest for the current action
@@ -22,10 +24,9 @@ module ActionController
22
24
  include ActionController::ConditionalGet
23
25
 
24
26
  included do
25
- class_attribute :etag_with_template_digest
26
- self.etag_with_template_digest = true
27
+ class_attribute :etag_with_template_digest, default: true
27
28
 
28
- ActiveSupport.on_load :action_view, yield: true do |action_view_base|
29
+ ActiveSupport.on_load :action_view, yield: true do
29
30
  etag do |options|
30
31
  determine_template_etag(options) if etag_with_template_digest
31
32
  end
@@ -33,18 +34,24 @@ module ActionController
33
34
  end
34
35
 
35
36
  private
36
- def determine_template_etag(options)
37
- if template = pick_template_for_etag(options)
38
- lookup_and_digest_template(template)
37
+ def determine_template_etag(options)
38
+ if template = pick_template_for_etag(options)
39
+ lookup_and_digest_template(template)
40
+ end
39
41
  end
40
- end
41
42
 
42
- def pick_template_for_etag(options)
43
- options.fetch(:template) { "#{controller_name}/#{action_name}" }
44
- end
43
+ # Pick the template digest to include in the ETag. If the +:template+ option
44
+ # is present, use the named template. If +:template+ is +nil+ or absent, use
45
+ # the default controller/action template. If +:template+ is false, omit the
46
+ # template digest from the ETag.
47
+ def pick_template_for_etag(options)
48
+ unless options[:template] == false
49
+ options[:template] || "#{controller_path}/#{action_name}"
50
+ end
51
+ end
45
52
 
46
- def lookup_and_digest_template(template)
47
- ActionView::Digestor.digest name: template, finder: lookup_context
48
- end
53
+ def lookup_and_digest_template(template)
54
+ ActionView::Digestor.digest name: template, format: nil, finder: lookup_context
55
+ end
49
56
  end
50
57
  end
@@ -1,16 +1,13 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  class ActionControllerError < StandardError #:nodoc:
3
5
  end
4
6
 
5
7
  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
8
+ def initialize(msg = nil)
9
+ super(msg)
10
+ set_backtrace $!.backtrace if $!
14
11
  end
15
12
  end
16
13
 
@@ -19,32 +16,29 @@ module ActionController
19
16
 
20
17
  class RoutingError < ActionControllerError #:nodoc:
21
18
  attr_reader :failures
22
- def initialize(message, failures=[])
19
+ def initialize(message, failures = [])
23
20
  super(message)
24
21
  @failures = failures
25
22
  end
26
23
  end
27
24
 
28
- class ActionController::UrlGenerationError < ActionControllerError #:nodoc:
25
+ class UrlGenerationError < ActionControllerError #:nodoc:
29
26
  end
30
27
 
31
28
  class MethodNotAllowed < ActionControllerError #:nodoc:
32
29
  def initialize(*allowed_methods)
33
- super("Only #{allowed_methods.to_sentence(:locale => :en)} requests are allowed.")
30
+ super("Only #{allowed_methods.to_sentence} requests are allowed.")
34
31
  end
35
32
  end
36
33
 
37
34
  class NotImplemented < MethodNotAllowed #:nodoc:
38
35
  end
39
36
 
40
- class UnknownController < ActionControllerError #:nodoc:
41
- end
42
-
43
37
  class MissingFile < ActionControllerError #:nodoc:
44
38
  end
45
39
 
46
40
  class SessionOverflowError < ActionControllerError #:nodoc:
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.'
41
+ 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."
48
42
 
49
43
  def initialize(message = nil)
50
44
  super(message || DEFAULT_MESSAGE)
@@ -56,4 +50,25 @@ module ActionController
56
50
 
57
51
  class UnknownFormat < ActionControllerError #:nodoc:
58
52
  end
53
+
54
+ # Raised when a nested respond_to is triggered and the content types of each
55
+ # are incompatible. For example:
56
+ #
57
+ # respond_to do |outer_type|
58
+ # outer_type.js do
59
+ # respond_to do |inner_type|
60
+ # inner_type.html { render body: "HTML" }
61
+ # end
62
+ # end
63
+ # end
64
+ class RespondToMismatchError < ActionControllerError
65
+ DEFAULT_MESSAGE = "respond_to was called multiple times and matched with conflicting formats in this action. Please note that you may only call respond_to and match on a single format per action."
66
+
67
+ def initialize(message = nil)
68
+ super(message || DEFAULT_MESSAGE)
69
+ end
70
+ end
71
+
72
+ class MissingExactTemplate < UnknownFormat #:nodoc:
73
+ end
59
74
  end
@@ -1,10 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController #:nodoc:
2
4
  module Flash
3
5
  extend ActiveSupport::Concern
4
6
 
5
7
  included do
6
- class_attribute :_flash_types, instance_accessor: false
7
- self._flash_types = []
8
+ class_attribute :_flash_types, instance_accessor: false, default: []
8
9
 
9
10
  delegate :flash, to: :request
10
11
  add_flash_types(:alert, :notice)
@@ -35,26 +36,26 @@ module ActionController #:nodoc:
35
36
  define_method(type) do
36
37
  request.flash[type]
37
38
  end
38
- helper_method type
39
+ helper_method(type) if respond_to?(:helper_method)
39
40
 
40
41
  self._flash_types += [type]
41
42
  end
42
43
  end
43
44
  end
44
45
 
45
- protected
46
- def redirect_to(options = {}, response_status_and_flash = {}) #:doc:
46
+ private
47
+ def redirect_to(options = {}, response_options_and_flash = {}) #:doc:
47
48
  self.class._flash_types.each do |flash_type|
48
- if type = response_status_and_flash.delete(flash_type)
49
+ if type = response_options_and_flash.delete(flash_type)
49
50
  flash[flash_type] = type
50
51
  end
51
52
  end
52
53
 
53
- if other_flashes = response_status_and_flash.delete(:flash)
54
+ if other_flashes = response_options_and_flash.delete(:flash)
54
55
  flash.update(other_flashes)
55
56
  end
56
57
 
57
- super(options, response_status_and_flash)
58
+ super(options, response_options_and_flash)
58
59
  end
59
60
  end
60
61
  end
@@ -1,19 +1,13 @@
1
- require 'active_support/core_ext/hash/except'
2
- require 'active_support/core_ext/hash/slice'
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/hash/except"
4
+ require "active_support/core_ext/hash/slice"
3
5
 
4
6
  module ActionController
5
- # This module provides a method which will redirect browser to use HTTPS
6
- # protocol. This will ensure that user's sensitive information will be
7
- # transferred safely over the internet. You _should_ always force browser
8
- # to use HTTPS when you're transferring sensitive information such as
9
- # user authentication, account information, or credit card information.
10
- #
11
- # Note that if you are really concerned about your application security,
12
- # you might consider using +config.force_ssl+ in your config file instead.
13
- # That will ensure all the data transferred via HTTPS protocol and prevent
14
- # user from getting session hijacked when accessing the site under unsecured
15
- # HTTP protocol.
16
- module ForceSSL
7
+ # This module is deprecated in favor of +config.force_ssl+ in your environment
8
+ # config file. This will ensure all endpoints not explicitly marked otherwise
9
+ # will have all communication served over HTTPS.
10
+ module ForceSSL # :nodoc:
17
11
  extend ActiveSupport::Concern
18
12
  include AbstractController::Callbacks
19
13
 
@@ -21,45 +15,17 @@ module ActionController
21
15
  URL_OPTIONS = [:protocol, :host, :domain, :subdomain, :port, :path]
22
16
  REDIRECT_OPTIONS = [:status, :flash, :alert, :notice]
23
17
 
24
- module ClassMethods
25
- # Force the request to this particular controller or specified actions to be
26
- # under HTTPS protocol.
27
- #
28
- # If you need to disable this for any reason (e.g. development) then you can use
29
- # an +:if+ or +:unless+ condition.
30
- #
31
- # class AccountsController < ApplicationController
32
- # force_ssl if: :ssl_configured?
33
- #
34
- # def ssl_configured?
35
- # !Rails.env.development?
36
- # end
37
- # end
38
- #
39
- # ==== URL Options
40
- # You can pass any of the following options to affect the redirect url
41
- # * <tt>host</tt> - Redirect to a different host name
42
- # * <tt>subdomain</tt> - Redirect to a different subdomain
43
- # * <tt>domain</tt> - Redirect to a different domain
44
- # * <tt>port</tt> - Redirect to a non-standard port
45
- # * <tt>path</tt> - Redirect to a different path
46
- #
47
- # ==== Redirect Options
48
- # You can pass any of the following options to affect the redirect status and response
49
- # * <tt>status</tt> - Redirect with a custom status (default is 301 Moved Permanently)
50
- # * <tt>flash</tt> - Set a flash message when redirecting
51
- # * <tt>alert</tt> - Set an alert message when redirecting
52
- # * <tt>notice</tt> - Set a notice message when redirecting
53
- #
54
- # ==== Action Options
55
- # You can pass any of the following options to affect the before_action callback
56
- # * <tt>only</tt> - The callback should be run only for this action
57
- # * <tt>except</tt> - The callback should be run for all actions except this action
58
- # * <tt>if</tt> - A symbol naming an instance method or a proc; the callback
59
- # will be called only when it returns a true value.
60
- # * <tt>unless</tt> - A symbol naming an instance method or a proc; the callback
61
- # will be called only when it returns a false value.
18
+ module ClassMethods # :nodoc:
62
19
  def force_ssl(options = {})
20
+ ActiveSupport::Deprecation.warn(<<-MESSAGE.squish)
21
+ Controller-level `force_ssl` is deprecated and will be removed from
22
+ Rails 6.1. Please enable `config.force_ssl` in your environment
23
+ configuration to enable the ActionDispatch::SSL middleware to more
24
+ fully enforce that your application communicate over HTTPS. If needed,
25
+ you can use `config.ssl_options` to exempt matching endpoints from
26
+ being redirected to HTTPS.
27
+ MESSAGE
28
+
63
29
  action_options = options.slice(*ACTION_OPTIONS)
64
30
  redirect_options = options.except(*ACTION_OPTIONS)
65
31
  before_action(action_options) do
@@ -68,18 +34,13 @@ module ActionController
68
34
  end
69
35
  end
70
36
 
71
- # Redirect the existing request to use the HTTPS protocol.
72
- #
73
- # ==== Parameters
74
- # * <tt>host_or_options</tt> - Either a host name or any of the url & redirect options
75
- # available to the <tt>force_ssl</tt> method.
76
37
  def force_ssl_redirect(host_or_options = nil)
77
38
  unless request.ssl?
78
39
  options = {
79
- :protocol => 'https://',
80
- :host => request.host,
81
- :path => request.fullpath,
82
- :status => :moved_permanently
40
+ protocol: "https://",
41
+ host: request.host,
42
+ path: request.fullpath,
43
+ status: :moved_permanently,
83
44
  }
84
45
 
85
46
  if host_or_options.is_a?(Hash)
@@ -89,7 +50,7 @@ module ActionController
89
50
  end
90
51
 
91
52
  secure_url = ActionDispatch::Http::URL.url_for(options.slice(*URL_OPTIONS))
92
- flash.keep if respond_to?(:flash)
53
+ flash.keep if respond_to?(:flash) && request.respond_to?(:flash)
93
54
  redirect_to secure_url, options.slice(*REDIRECT_OPTIONS)
94
55
  end
95
56
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  module Head
3
5
  # Returns a response that has no content (merely headers). The options
@@ -17,13 +19,17 @@ module ActionController
17
19
  #
18
20
  # See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list of valid +status+ symbols.
19
21
  def head(status, options = {})
20
- options, status = status, nil if status.is_a?(Hash)
21
- status ||= options.delete(:status) || :ok
22
+ if status.is_a?(Hash)
23
+ raise ArgumentError, "#{status.inspect} is not a valid value for `status`."
24
+ end
25
+
26
+ status ||= :ok
27
+
22
28
  location = options.delete(:location)
23
29
  content_type = options.delete(:content_type)
24
30
 
25
31
  options.each do |key, value|
26
- headers[key.to_s.dasherize.split('-').each { |v| v[0] = v[0].chr.upcase }.join('-')] = value.to_s
32
+ headers[key.to_s.dasherize.split("-").each { |v| v[0] = v[0].chr.upcase }.join("-")] = value.to_s
27
33
  end
28
34
 
29
35
  self.status = status
@@ -31,28 +37,24 @@ module ActionController
31
37
 
32
38
  self.response_body = ""
33
39
 
34
- if include_content?(self.response_code)
35
- self.content_type = content_type || (Mime[formats.first] if formats)
36
- self.response.charset = false if self.response
37
- else
38
- headers.delete('Content-Type')
39
- headers.delete('Content-Length')
40
+ if include_content?(response_code)
41
+ self.content_type = content_type || (Mime[formats.first] if formats) || Mime[:html]
42
+ response.charset = false
40
43
  end
41
-
44
+
42
45
  true
43
46
  end
44
47
 
45
48
  private
46
- # :nodoc:
47
- def include_content?(status)
48
- case status
49
- when 100..199
50
- false
51
- when 204, 205, 304
52
- false
53
- else
54
- true
49
+ def include_content?(status)
50
+ case status
51
+ when 100..199
52
+ false
53
+ when 204, 205, 304
54
+ false
55
+ else
56
+ true
57
+ end
55
58
  end
56
- end
57
59
  end
58
60
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module ActionController
2
4
  # The \Rails framework provides a large number of helpers for working with assets, dates, forms,
3
5
  # numbers and model objects, to name a few. These helpers are available to all templates
@@ -5,10 +7,10 @@ module ActionController
5
7
  #
6
8
  # In addition to using the standard template helpers provided, creating custom helpers to
7
9
  # extract complicated logic or reusable functionality is strongly encouraged. By default, each controller
8
- # will include all helpers. These helpers are only accessible on the controller through <tt>.helpers</tt>
10
+ # will include all helpers. These helpers are only accessible on the controller through <tt>#helpers</tt>
9
11
  #
10
- # In previous versions of \Rails the controller will include a helper whose
11
- # name matches that of the controller, e.g., <tt>MyController</tt> will automatically
12
+ # In previous versions of \Rails the controller will include a helper which
13
+ # matches the name of the controller, e.g., <tt>MyController</tt> will automatically
12
14
  # include <tt>MyHelper</tt>. To return old behavior set +config.action_controller.include_all_helpers+ to +false+.
13
15
  #
14
16
  # Additional helpers can be specified using the +helper+ class method in ActionController::Base or any
@@ -32,7 +34,7 @@ module ActionController
32
34
  # end
33
35
  # end
34
36
  #
35
- # Then, in any view rendered by <tt>EventController</tt>, the <tt>format_time</tt> method can be called:
37
+ # Then, in any view rendered by <tt>EventsController</tt>, the <tt>format_time</tt> method can be called:
36
38
  #
37
39
  # <% @events.each do |event| -%>
38
40
  # <p>
@@ -44,7 +46,7 @@ module ActionController
44
46
  # the output might look like this:
45
47
  #
46
48
  # 23 Aug 11:30 | Carolina Railhawks Soccer Match
47
- # N/A | Carolina Railhaws Training Workshop
49
+ # N/A | Carolina Railhawks Training Workshop
48
50
  #
49
51
  module Helpers
50
52
  extend ActiveSupport::Concern
@@ -53,9 +55,8 @@ module ActionController
53
55
  include AbstractController::Helpers
54
56
 
55
57
  included do
56
- class_attribute :helpers_path, :include_all_helpers
57
- self.helpers_path ||= []
58
- self.include_all_helpers = true
58
+ class_attribute :helpers_path, default: []
59
+ class_attribute :include_all_helpers, default: true
59
60
  end
60
61
 
61
62
  module ClassMethods
@@ -71,10 +72,10 @@ module ActionController
71
72
  attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
72
73
  end
73
74
 
74
- # Provides a proxy to access helpers methods from outside the view.
75
+ # Provides a proxy to access helper methods from outside the view.
75
76
  def helpers
76
- @helper_proxy ||= begin
77
- proxy = ActionView::Base.new
77
+ @helper_proxy ||= begin
78
+ proxy = ActionView::Base.empty
78
79
  proxy.config = config.inheritable_copy
79
80
  proxy.extend(_helpers)
80
81
  end
@@ -93,10 +94,13 @@ module ActionController
93
94
  super(args)
94
95
  end
95
96
 
97
+ # Returns a list of helper names in a given path.
98
+ #
99
+ # ActionController::Base.all_helpers_from_path 'app/helpers'
100
+ # # => ["application", "chart", "rubygems"]
96
101
  def all_helpers_from_path(path)
97
102
  helpers = Array(path).flat_map do |_path|
98
- extract = /^#{Regexp.quote(_path.to_s)}\/?(.*)_helper.rb$/
99
- names = Dir["#{_path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') }
103
+ names = Dir["#{_path}/**/*_helper.rb"].map { |file| file[_path.to_s.size + 1..-"_helper.rb".size - 1] }
100
104
  names.sort!
101
105
  end
102
106
  helpers.uniq!
@@ -104,10 +108,15 @@ module ActionController
104
108
  end
105
109
 
106
110
  private
107
- # Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
108
- def all_application_helpers
109
- all_helpers_from_path(helpers_path)
110
- end
111
+ # Extract helper names from files in <tt>app/helpers/**/*_helper.rb</tt>
112
+ def all_application_helpers
113
+ all_helpers_from_path(helpers_path)
114
+ end
115
+ end
116
+
117
+ # Provides a proxy to access helper methods from outside the view.
118
+ def helpers
119
+ @_helper_proxy ||= view_context
111
120
  end
112
121
  end
113
122
  end