actionpack 7.1.3.4 → 7.2.0.beta1

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 (158) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +70 -541
  3. data/lib/abstract_controller/asset_paths.rb +2 -0
  4. data/lib/abstract_controller/base.rb +102 -98
  5. data/lib/abstract_controller/caching/fragments.rb +50 -53
  6. data/lib/abstract_controller/caching.rb +2 -0
  7. data/lib/abstract_controller/callbacks.rb +66 -64
  8. data/lib/abstract_controller/collector.rb +6 -6
  9. data/lib/abstract_controller/deprecator.rb +2 -0
  10. data/lib/abstract_controller/error.rb +2 -0
  11. data/lib/abstract_controller/helpers.rb +70 -85
  12. data/lib/abstract_controller/logger.rb +2 -0
  13. data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
  14. data/lib/abstract_controller/rendering.rb +13 -12
  15. data/lib/abstract_controller/translation.rb +11 -10
  16. data/lib/abstract_controller/url_for.rb +8 -6
  17. data/lib/abstract_controller.rb +2 -0
  18. data/lib/action_controller/api/api_rendering.rb +2 -0
  19. data/lib/action_controller/api.rb +74 -72
  20. data/lib/action_controller/base.rb +155 -117
  21. data/lib/action_controller/caching.rb +15 -12
  22. data/lib/action_controller/deprecator.rb +2 -0
  23. data/lib/action_controller/form_builder.rb +20 -17
  24. data/lib/action_controller/log_subscriber.rb +3 -1
  25. data/lib/action_controller/metal/allow_browser.rb +119 -0
  26. data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
  27. data/lib/action_controller/metal/conditional_get.rb +188 -174
  28. data/lib/action_controller/metal/content_security_policy.rb +25 -24
  29. data/lib/action_controller/metal/cookies.rb +4 -2
  30. data/lib/action_controller/metal/data_streaming.rb +64 -55
  31. data/lib/action_controller/metal/default_headers.rb +5 -3
  32. data/lib/action_controller/metal/etag_with_flash.rb +3 -1
  33. data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
  34. data/lib/action_controller/metal/exceptions.rb +11 -9
  35. data/lib/action_controller/metal/flash.rb +12 -10
  36. data/lib/action_controller/metal/head.rb +12 -10
  37. data/lib/action_controller/metal/helpers.rb +63 -55
  38. data/lib/action_controller/metal/http_authentication.rb +209 -201
  39. data/lib/action_controller/metal/implicit_render.rb +17 -15
  40. data/lib/action_controller/metal/instrumentation.rb +15 -12
  41. data/lib/action_controller/metal/live.rb +113 -107
  42. data/lib/action_controller/metal/logging.rb +6 -4
  43. data/lib/action_controller/metal/mime_responds.rb +151 -142
  44. data/lib/action_controller/metal/parameter_encoding.rb +34 -32
  45. data/lib/action_controller/metal/params_wrapper.rb +57 -59
  46. data/lib/action_controller/metal/permissions_policy.rb +13 -12
  47. data/lib/action_controller/metal/rate_limiting.rb +62 -0
  48. data/lib/action_controller/metal/redirecting.rb +108 -82
  49. data/lib/action_controller/metal/renderers.rb +50 -49
  50. data/lib/action_controller/metal/rendering.rb +103 -75
  51. data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
  52. data/lib/action_controller/metal/rescue.rb +11 -9
  53. data/lib/action_controller/metal/streaming.rb +138 -136
  54. data/lib/action_controller/metal/strong_parameters.rb +525 -480
  55. data/lib/action_controller/metal/testing.rb +2 -0
  56. data/lib/action_controller/metal/url_for.rb +17 -15
  57. data/lib/action_controller/metal.rb +58 -57
  58. data/lib/action_controller/railtie.rb +3 -0
  59. data/lib/action_controller/railties/helpers.rb +2 -0
  60. data/lib/action_controller/renderer.rb +42 -36
  61. data/lib/action_controller/template_assertions.rb +4 -2
  62. data/lib/action_controller/test_case.rb +146 -126
  63. data/lib/action_controller.rb +10 -3
  64. data/lib/action_dispatch/constants.rb +2 -0
  65. data/lib/action_dispatch/deprecator.rb +2 -0
  66. data/lib/action_dispatch/http/cache.rb +27 -26
  67. data/lib/action_dispatch/http/content_disposition.rb +2 -0
  68. data/lib/action_dispatch/http/content_security_policy.rb +44 -38
  69. data/lib/action_dispatch/http/filter_parameters.rb +9 -5
  70. data/lib/action_dispatch/http/filter_redirect.rb +15 -1
  71. data/lib/action_dispatch/http/headers.rb +22 -22
  72. data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
  73. data/lib/action_dispatch/http/mime_type.rb +29 -22
  74. data/lib/action_dispatch/http/mime_types.rb +2 -0
  75. data/lib/action_dispatch/http/parameters.rb +11 -9
  76. data/lib/action_dispatch/http/permissions_policy.rb +27 -37
  77. data/lib/action_dispatch/http/rack_cache.rb +2 -0
  78. data/lib/action_dispatch/http/request.rb +71 -71
  79. data/lib/action_dispatch/http/response.rb +61 -61
  80. data/lib/action_dispatch/http/upload.rb +18 -16
  81. data/lib/action_dispatch/http/url.rb +75 -73
  82. data/lib/action_dispatch/journey/formatter.rb +13 -6
  83. data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
  84. data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
  85. data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
  86. data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +6 -5
  88. data/lib/action_dispatch/journey/parser.rb +4 -3
  89. data/lib/action_dispatch/journey/parser_extras.rb +2 -0
  90. data/lib/action_dispatch/journey/path/pattern.rb +4 -1
  91. data/lib/action_dispatch/journey/route.rb +9 -7
  92. data/lib/action_dispatch/journey/router/utils.rb +16 -15
  93. data/lib/action_dispatch/journey/router.rb +4 -2
  94. data/lib/action_dispatch/journey/routes.rb +4 -2
  95. data/lib/action_dispatch/journey/scanner.rb +4 -2
  96. data/lib/action_dispatch/journey/visitors.rb +2 -0
  97. data/lib/action_dispatch/journey.rb +2 -0
  98. data/lib/action_dispatch/log_subscriber.rb +2 -0
  99. data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
  100. data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
  101. data/lib/action_dispatch/middleware/callbacks.rb +3 -1
  102. data/lib/action_dispatch/middleware/cookies.rb +119 -104
  103. data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
  104. data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
  105. data/lib/action_dispatch/middleware/debug_view.rb +2 -0
  106. data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
  107. data/lib/action_dispatch/middleware/executor.rb +8 -0
  108. data/lib/action_dispatch/middleware/flash.rb +63 -51
  109. data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
  110. data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
  111. data/lib/action_dispatch/middleware/reloader.rb +5 -3
  112. data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
  113. data/lib/action_dispatch/middleware/request_id.rb +14 -9
  114. data/lib/action_dispatch/middleware/server_timing.rb +4 -2
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
  120. data/lib/action_dispatch/middleware/ssl.rb +43 -40
  121. data/lib/action_dispatch/middleware/stack.rb +11 -10
  122. data/lib/action_dispatch/middleware/static.rb +33 -31
  123. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
  124. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
  125. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
  126. data/lib/action_dispatch/railtie.rb +2 -4
  127. data/lib/action_dispatch/request/session.rb +23 -21
  128. data/lib/action_dispatch/request/utils.rb +2 -0
  129. data/lib/action_dispatch/routing/endpoint.rb +2 -0
  130. data/lib/action_dispatch/routing/inspector.rb +5 -3
  131. data/lib/action_dispatch/routing/mapper.rb +670 -635
  132. data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
  133. data/lib/action_dispatch/routing/redirection.rb +37 -32
  134. data/lib/action_dispatch/routing/route_set.rb +59 -45
  135. data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
  136. data/lib/action_dispatch/routing/url_for.rb +130 -125
  137. data/lib/action_dispatch/routing.rb +150 -148
  138. data/lib/action_dispatch/system_test_case.rb +91 -81
  139. data/lib/action_dispatch/system_testing/browser.rb +10 -3
  140. data/lib/action_dispatch/system_testing/driver.rb +3 -1
  141. data/lib/action_dispatch/system_testing/server.rb +2 -0
  142. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
  143. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
  144. data/lib/action_dispatch/testing/assertion_response.rb +8 -6
  145. data/lib/action_dispatch/testing/assertions/response.rb +26 -23
  146. data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
  147. data/lib/action_dispatch/testing/assertions.rb +2 -0
  148. data/lib/action_dispatch/testing/integration.rb +223 -222
  149. data/lib/action_dispatch/testing/request_encoder.rb +2 -0
  150. data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
  151. data/lib/action_dispatch/testing/test_process.rb +12 -8
  152. data/lib/action_dispatch/testing/test_request.rb +3 -1
  153. data/lib/action_dispatch/testing/test_response.rb +27 -26
  154. data/lib/action_dispatch.rb +22 -28
  155. data/lib/action_pack/gem_version.rb +6 -4
  156. data/lib/action_pack/version.rb +3 -1
  157. data/lib/action_pack.rb +17 -16
  158. metadata +30 -13
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/notifications"
4
6
 
5
7
  module ActionDispatch
@@ -29,8 +31,8 @@ module ActionDispatch
29
31
 
30
32
  def ensure_subscribed
31
33
  @mutex.synchronize do
32
- # Subscribe to all events, except those beginning with "!"
33
- # Ideally we would be more selective of what is being measured
34
+ # Subscribe to all events, except those beginning with "!" Ideally we would be
35
+ # more selective of what is being measured
34
36
  @subscriber ||= ActiveSupport::Notifications.subscribe(/\A[^!]/, self)
35
37
  end
36
38
  end
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "rack/utils"
4
6
  require "rack/request"
5
7
  require "rack/session/abstract/id"
@@ -1,19 +1,24 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/middleware/session/abstract_store"
4
6
 
5
7
  module ActionDispatch
6
8
  module Session
7
- # = Action Dispatch Session \CacheStore
9
+ # # Action Dispatch Session CacheStore
10
+ #
11
+ # A session store that uses an ActiveSupport::Cache::Store to store the
12
+ # sessions. This store is most useful if you don't store critical data in your
13
+ # sessions and you don't need them to live for extended periods of time.
8
14
  #
9
- # A session store that uses an ActiveSupport::Cache::Store to store the sessions. This store is most useful
10
- # if you don't store critical data in your sessions and you don't need them to live for extended periods
11
- # of time.
15
+ # #### Options
16
+ # * `cache` - The cache to use. If it is not specified, `Rails.cache`
17
+ # will be used.
18
+ # * `expire_after` - The length of time a session will be stored before
19
+ # automatically expiring. By default, the `:expires_in` option of the cache
20
+ # is used.
12
21
  #
13
- # ==== Options
14
- # * <tt>cache</tt> - The cache to use. If it is not specified, <tt>Rails.cache</tt> will be used.
15
- # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring.
16
- # By default, the <tt>:expires_in</tt> option of the cache is used.
17
22
  class CacheStore < AbstractSecureStore
18
23
  def initialize(app, options = {})
19
24
  @cache = options[:cache] || Rails.cache
@@ -1,53 +1,54 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/core_ext/hash/keys"
4
6
  require "action_dispatch/middleware/session/abstract_store"
5
7
  require "rack/session/cookie"
6
8
 
7
9
  module ActionDispatch
8
10
  module Session
9
- # = Action Dispatch Session \CookieStore
11
+ # # Action Dispatch Session CookieStore
10
12
  #
11
- # This cookie-based session store is the \Rails default. It is
12
- # dramatically faster than the alternatives.
13
+ # This cookie-based session store is the Rails default. It is dramatically
14
+ # faster than the alternatives.
13
15
  #
14
16
  # Sessions typically contain at most a user ID and flash message; both fit
15
- # within the 4096 bytes cookie size limit. A +CookieOverflow+ exception is raised if
16
- # you attempt to store more than 4096 bytes of data.
17
+ # within the 4096 bytes cookie size limit. A `CookieOverflow` exception is
18
+ # raised if you attempt to store more than 4096 bytes of data.
17
19
  #
18
- # The cookie jar used for storage is automatically configured to be the
19
- # best possible option given your application's configuration.
20
+ # The cookie jar used for storage is automatically configured to be the best
21
+ # possible option given your application's configuration.
20
22
  #
21
- # Your cookies will be encrypted using your application's +secret_key_base+. This
22
- # goes a step further than signed cookies in that encrypted cookies cannot
23
- # be altered or read by users. This is the default starting in \Rails 4.
23
+ # Your cookies will be encrypted using your application's `secret_key_base`.
24
+ # This goes a step further than signed cookies in that encrypted cookies cannot
25
+ # be altered or read by users. This is the default starting in Rails 4.
24
26
  #
25
27
  # Configure your session store in an initializer:
26
28
  #
27
- # Rails.application.config.session_store :cookie_store, key: '_your_app_session'
29
+ # Rails.application.config.session_store :cookie_store, key: '_your_app_session'
28
30
  #
29
- # In the development and test environments your application's +secret_key_base+ is
30
- # generated by \Rails and stored in a temporary file in <tt>tmp/local_secret.txt</tt>.
31
- # In all other environments, it is stored encrypted in the
32
- # <tt>config/credentials.yml.enc</tt> file.
31
+ # In the development and test environments your application's `secret_key_base`
32
+ # is generated by Rails and stored in a temporary file in
33
+ # `tmp/local_secret.txt`. In all other environments, it is stored encrypted in
34
+ # the `config/credentials.yml.enc` file.
33
35
  #
34
- # If your application was not updated to \Rails 5.2 defaults, the +secret_key_base+
35
- # will be found in the old <tt>config/secrets.yml</tt> file.
36
+ # If your application was not updated to Rails 5.2 defaults, the
37
+ # `secret_key_base` will be found in the old `config/secrets.yml` file.
36
38
  #
37
- # Note that changing your +secret_key_base+ will invalidate all existing session.
38
- # Additionally, you should take care to make sure you are not relying on the
39
- # ability to decode signed cookies generated by your app in external
39
+ # Note that changing your `secret_key_base` will invalidate all existing
40
+ # session. Additionally, you should take care to make sure you are not relying
41
+ # on the ability to decode signed cookies generated by your app in external
40
42
  # applications or JavaScript before changing it.
41
43
  #
42
- # Because CookieStore extends +Rack::Session::Abstract::Persisted+, many of the
43
- # options described there can be used to customize the session cookie that
44
- # is generated. For example:
44
+ # Because CookieStore extends `Rack::Session::Abstract::Persisted`, many of the
45
+ # options described there can be used to customize the session cookie that is
46
+ # generated. For example:
45
47
  #
46
- # Rails.application.config.session_store :cookie_store, expire_after: 14.days
48
+ # Rails.application.config.session_store :cookie_store, expire_after: 14.days
47
49
  #
48
50
  # would set the session cookie to expire automatically 14 days after creation.
49
- # Other useful options include <tt>:key</tt>, <tt>:secure</tt>,
50
- # <tt>:httponly</tt>, and <tt>:same_site</tt>.
51
+ # Other useful options include `:key`, `:secure`, `:httponly`, and `:same_site`.
51
52
  class CookieStore < AbstractSecureStore
52
53
  class SessionId < DelegateClass(Rack::Session::SessionId)
53
54
  attr_reader :cookie_value
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/middleware/session/abstract_store"
4
6
  begin
5
7
  require "rack/session/dalli"
@@ -10,12 +12,14 @@ end
10
12
 
11
13
  module ActionDispatch
12
14
  module Session
13
- # = Action Dispatch Session \MemCacheStore
15
+ # # Action Dispatch Session MemCacheStore
14
16
  #
15
17
  # A session store that uses MemCache to implement storage.
16
18
  #
17
- # ==== Options
18
- # * <tt>expire_after</tt> - The length of time a session will be stored before automatically expiring.
19
+ # #### Options
20
+ # * `expire_after` - The length of time a session will be stored before
21
+ # automatically expiring.
22
+ #
19
23
  class MemCacheStore < Rack::Session::Dalli
20
24
  include Compatibility
21
25
  include StaleSessionCheck
@@ -1,26 +1,27 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch/middleware/exception_wrapper"
4
6
 
5
7
  module ActionDispatch
6
- # = Action Dispatch \ShowExceptions
8
+ # # Action Dispatch ShowExceptions
7
9
  #
8
- # This middleware rescues any exception returned by the application
9
- # and calls an exceptions app that will wrap it in a format for the end user.
10
+ # This middleware rescues any exception returned by the application and calls an
11
+ # exceptions app that will wrap it in a format for the end user.
10
12
  #
11
13
  # The exceptions app should be passed as a parameter on initialization of
12
- # +ShowExceptions+. Every time there is an exception, +ShowExceptions+ will
13
- # store the exception in <tt>env["action_dispatch.exception"]</tt>, rewrite
14
- # the +PATH_INFO+ to the exception status code, and call the Rack app.
14
+ # `ShowExceptions`. Every time there is an exception, `ShowExceptions` will
15
+ # store the exception in `env["action_dispatch.exception"]`, rewrite the
16
+ # `PATH_INFO` to the exception status code, and call the Rack app.
15
17
  #
16
- # In \Rails applications, the exceptions app can be configured with
17
- # +config.exceptions_app+, which defaults to ActionDispatch::PublicExceptions.
18
+ # In Rails applications, the exceptions app can be configured with
19
+ # `config.exceptions_app`, which defaults to ActionDispatch::PublicExceptions.
18
20
  #
19
- # If the application returns a response with the <tt>X-Cascade</tt> header
20
- # set to <tt>"pass"</tt>, this middleware will send an empty response as a
21
- # result with the correct status code. If any exception happens inside the
22
- # exceptions app, this middleware catches the exceptions and returns a
23
- # failsafe response.
21
+ # If the application returns a response with the `X-Cascade` header set to
22
+ # `"pass"`, this middleware will send an empty response as a result with the
23
+ # correct status code. If any exception happens inside the exceptions app, this
24
+ # middleware catches the exceptions and returns a failsafe response.
24
25
  class ShowExceptions
25
26
  def initialize(app, exceptions_app)
26
27
  @app = app
@@ -33,8 +34,11 @@ module ActionDispatch
33
34
  request = ActionDispatch::Request.new env
34
35
  backtrace_cleaner = request.get_header("action_dispatch.backtrace_cleaner")
35
36
  wrapper = ExceptionWrapper.new(backtrace_cleaner, exception)
37
+ request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
38
+ request.set_header "action_dispatch.report_exception", !wrapper.rescue_response?
39
+
36
40
  if wrapper.show?(request)
37
- render_exception(request, wrapper)
41
+ render_exception(request.dup, wrapper)
38
42
  else
39
43
  raise exception
40
44
  end
@@ -43,7 +47,6 @@ module ActionDispatch
43
47
  private
44
48
  def render_exception(request, wrapper)
45
49
  status = wrapper.status_code
46
- request.set_header "action_dispatch.exception", wrapper.unwrapped_exception
47
50
  request.set_header "action_dispatch.original_path", request.path_info
48
51
  request.set_header "action_dispatch.original_request_method", request.raw_request_method
49
52
  fallback_to_html_format_if_invalid_mime_type(request)
@@ -62,12 +65,19 @@ module ActionDispatch
62
65
  end
63
66
 
64
67
  def fallback_to_html_format_if_invalid_mime_type(request)
65
- # If the MIME type for the request is invalid then the
66
- # @exceptions_app may not be able to handle it. To make it
67
- # easier to handle, we switch to HTML.
68
- request.formats
69
- rescue ActionDispatch::Http::MimeNegotiation::InvalidType
70
- request.set_header "HTTP_ACCEPT", "text/html"
68
+ # If the MIME type for the request is invalid then the @exceptions_app may not
69
+ # be able to handle it. To make it easier to handle, we switch to HTML.
70
+ begin
71
+ request.content_mime_type
72
+ rescue ActionDispatch::Http::MimeNegotiation::InvalidType
73
+ request.set_header "CONTENT_TYPE", "text/html"
74
+ end
75
+
76
+ begin
77
+ request.formats
78
+ rescue ActionDispatch::Http::MimeNegotiation::InvalidType
79
+ request.set_header "HTTP_ACCEPT", "text/html"
80
+ end
71
81
  end
72
82
 
73
83
  def pass_response(status)
@@ -1,57 +1,60 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  module ActionDispatch
4
- # = Action Dispatch \SSL
6
+ # # Action Dispatch SSL
7
+ #
8
+ # This middleware is added to the stack when `config.force_ssl = true`, and is
9
+ # passed the options set in `config.ssl_options`. It does three jobs to enforce
10
+ # secure HTTP requests:
5
11
  #
6
- # This middleware is added to the stack when <tt>config.force_ssl = true</tt>, and is passed
7
- # the options set in +config.ssl_options+. It does three jobs to enforce secure HTTP
8
- # requests:
12
+ # 1. **TLS redirect**: Permanently redirects `http://` requests to `https://`
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.
9
17
  #
10
- # 1. <b>TLS redirect</b>: Permanently redirects +http://+ requests to +https://+
11
- # with the same URL host, path, etc. Enabled by default. Set +config.ssl_options+
12
- # to modify the destination URL
13
- # (e.g. <tt>redirect: { host: "secure.widgets.com", port: 8080 }</tt>), or set
14
- # <tt>redirect: false</tt> to disable this feature.
18
+ # Requests can opt-out of redirection with `exclude`:
15
19
  #
16
- # Requests can opt-out of redirection with +exclude+:
20
+ # config.ssl_options = { redirect: { exclude: -> request { /healthcheck/.match?(request.path) } } }
17
21
  #
18
- # config.ssl_options = { redirect: { exclude: -> request { /healthcheck/.match?(request.path) } } }
22
+ # Cookies will not be flagged as secure for excluded requests.
19
23
  #
20
- # Cookies will not be flagged as secure for excluded requests.
24
+ # 2. **Secure cookies**: Sets the `secure` flag on cookies to tell browsers
25
+ # they must not be sent along with `http://` requests. Enabled by default.
26
+ # Set `config.ssl_options` with `secure_cookies: false` to disable this
27
+ # feature.
21
28
  #
22
- # 2. <b>Secure cookies</b>: Sets the +secure+ flag on cookies to tell browsers they
23
- # must not be sent along with +http://+ requests. Enabled by default. Set
24
- # +config.ssl_options+ with <tt>secure_cookies: false</tt> to disable this feature.
29
+ # 3. **HTTP Strict Transport Security (HSTS)**: Tells the browser to remember
30
+ # this site as TLS-only and automatically redirect non-TLS requests. Enabled
31
+ # by default. Configure `config.ssl_options` with `hsts: false` to disable.
25
32
  #
26
- # 3. <b>HTTP Strict Transport Security (HSTS)</b>: Tells the browser to remember
27
- # this site as TLS-only and automatically redirect non-TLS requests.
28
- # Enabled by default. Configure +config.ssl_options+ with <tt>hsts: false</tt> to disable.
33
+ # Set `config.ssl_options` with `hsts: { ... }` to configure HSTS:
29
34
  #
30
- # Set +config.ssl_options+ with <tt>hsts: { ... }</tt> to configure HSTS:
35
+ # * `expires`: How long, in seconds, these settings will stick. The
36
+ # minimum required to qualify for browser preload lists is 1 year.
37
+ # Defaults to 2 years (recommended).
31
38
  #
32
- # * +expires+: How long, in seconds, these settings will stick. The minimum
33
- # required to qualify for browser preload lists is 1 year. Defaults to
34
- # 2 years (recommended).
39
+ # * `subdomains`: Set to `true` to tell the browser to apply these
40
+ # settings to all subdomains. This protects your cookies from
41
+ # interception by a vulnerable site on a subdomain. Defaults to `true`.
35
42
  #
36
- # * +subdomains+: Set to +true+ to tell the browser to apply these settings
37
- # to all subdomains. This protects your cookies from interception by a
38
- # vulnerable site on a subdomain. Defaults to +true+.
43
+ # * `preload`: Advertise that this site may be included in browsers'
44
+ # preloaded HSTS lists. HSTS protects your site on every visit *except
45
+ # the first visit* since it hasn't seen your HSTS header yet. To close
46
+ # this gap, browser vendors include a baked-in list of HSTS-enabled
47
+ # sites. Go to https://hstspreload.org to submit your site for
48
+ # inclusion. Defaults to `false`.
39
49
  #
40
- # * +preload+: Advertise that this site may be included in browsers'
41
- # preloaded HSTS lists. HSTS protects your site on every visit <i>except the
42
- # first visit</i> since it hasn't seen your HSTS header yet. To close this
43
- # gap, browser vendors include a baked-in list of HSTS-enabled sites.
44
- # Go to https://hstspreload.org to submit your site for inclusion.
45
- # Defaults to +false+.
46
50
  #
47
- # To turn off HSTS, omitting the header is not enough. Browsers will remember the
48
- # original HSTS directive until it expires. Instead, use the header to tell browsers to
49
- # expire HSTS immediately. Setting <tt>hsts: false</tt> is a shortcut for
50
- # <tt>hsts: { expires: 0 }</tt>.
51
+ # To turn off HSTS, omitting the header is not enough. Browsers will
52
+ # remember the original HSTS directive until it expires. Instead, use the
53
+ # header to tell browsers to expire HSTS immediately. Setting `hsts: false`
54
+ # is a shortcut for `hsts: { expires: 0 }`.
55
+ #
51
56
  class SSL
52
- # :stopdoc:
53
-
54
- # Default to 2 years as recommended on hstspreload.org.
57
+ # :stopdoc: Default to 2 years as recommended on hstspreload.org.
55
58
  HSTS_EXPIRES_IN = 63072000
56
59
 
57
60
  PERMANENT_REDIRECT_REQUEST_METHODS = %w[GET HEAD] # :nodoc:
@@ -93,8 +96,8 @@ module ActionDispatch
93
96
 
94
97
  def normalize_hsts_options(options)
95
98
  case options
96
- # Explicitly disabling HSTS clears the existing setting from browsers
97
- # by setting expiry to 0.
99
+ # Explicitly disabling HSTS clears the existing setting from browsers by setting
100
+ # expiry to 0.
98
101
  when false
99
102
  self.class.default_hsts_options.merge(expires: 0)
100
103
  # Default to enabled, with default options.
@@ -1,13 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "active_support/inflector/methods"
4
6
  require "active_support/dependencies"
5
7
 
6
8
  module ActionDispatch
7
- # = Action Dispatch \MiddlewareStack
9
+ # # Action Dispatch MiddlewareStack
8
10
  #
9
- # Read more about {Rails middleware
10
- # stack}[https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack]
11
+ # Read more about [Rails middleware
12
+ # stack](https://guides.rubyonrails.org/rails_on_rack.html#action-dispatcher-middleware-stack)
11
13
  # in the guides.
12
14
  class MiddlewareStack
13
15
  class Middleware
@@ -47,9 +49,8 @@ module ActionDispatch
47
49
  end
48
50
  end
49
51
 
50
- # This class is used to instrument the execution of a single middleware.
51
- # It proxies the +call+ method transparently and instruments the method
52
- # call.
52
+ # This class is used to instrument the execution of a single middleware. It
53
+ # proxies the `call` method transparently and instruments the method call.
53
54
  class InstrumentationProxy
54
55
  EVENT_NAME = "process_middleware.action_dispatch"
55
56
 
@@ -125,16 +126,16 @@ module ActionDispatch
125
126
 
126
127
  # Deletes a middleware from the middleware stack.
127
128
  #
128
- # Returns the array of middlewares not including the deleted item, or
129
- # returns nil if the target is not found.
129
+ # Returns the array of middlewares not including the deleted item, or returns
130
+ # nil if the target is not found.
130
131
  def delete(target)
131
132
  middlewares.reject! { |m| m.name == target.name }
132
133
  end
133
134
 
134
135
  # Deletes a middleware from the middleware stack.
135
136
  #
136
- # Returns the array of middlewares not including the deleted item, or
137
- # raises +RuntimeError+ if the target is not found.
137
+ # Returns the array of middlewares not including the deleted item, or raises
138
+ # `RuntimeError` if the target is not found.
138
139
  def delete!(target)
139
140
  delete(target) || (raise "No such middleware to remove: #{target.inspect}")
140
141
  end
@@ -1,18 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "rack/utils"
4
6
 
5
7
  module ActionDispatch
6
- # = Action Dispatch \Static
8
+ # # Action Dispatch Static
7
9
  #
8
- # This middleware serves static files from disk, if available.
9
- # If no file is found, it hands off to the main app.
10
+ # This middleware serves static files from disk, if available. If no file is
11
+ # found, it hands off to the main app.
10
12
  #
11
- # In \Rails apps, this middleware is configured to serve assets from
12
- # the +public/+ directory.
13
+ # In Rails apps, this middleware is configured to serve assets from the
14
+ # `public/` directory.
13
15
  #
14
- # Only GET and HEAD requests are served. POST and other HTTP methods
15
- # are handed off to the main app.
16
+ # Only GET and HEAD requests are served. POST and other HTTP methods are handed
17
+ # off to the main app.
16
18
  #
17
19
  # Only files in the root directory are served; path traversal is denied.
18
20
  class Static
@@ -26,31 +28,31 @@ module ActionDispatch
26
28
  end
27
29
  end
28
30
 
29
- # = Action Dispatch \FileHandler
31
+ # # Action Dispatch FileHandler
30
32
  #
31
- # This endpoint serves static files from disk using +Rack::Files+.
33
+ # This endpoint serves static files from disk using `Rack::Files`.
32
34
  #
33
- # URL paths are matched with static files according to expected
34
- # conventions: +path+, +path+.html, +path+/index.html.
35
+ # URL paths are matched with static files according to expected conventions:
36
+ # `path`, `path`.html, `path`/index.html.
35
37
  #
36
- # Precompressed versions of these files are checked first. Brotli (.br)
37
- # and gzip (.gz) files are supported. If +path+.br exists, this
38
- # endpoint returns that file with a <tt>content-encoding: br</tt> header.
38
+ # Precompressed versions of these files are checked first. Brotli (.br) and gzip
39
+ # (.gz) files are supported. If `path`.br exists, this endpoint returns that
40
+ # file with a `content-encoding: br` header.
39
41
  #
40
- # If no matching file is found, this endpoint responds <tt>404 Not Found</tt>.
42
+ # If no matching file is found, this endpoint responds `404 Not Found`.
41
43
  #
42
- # Pass the +root+ directory to search for matching files, an optional
43
- # <tt>index: "index"</tt> to change the default +path+/index.html, and optional
44
- # additional response headers.
44
+ # Pass the `root` directory to search for matching files, an optional `index:
45
+ # "index"` to change the default `path`/index.html, and optional additional
46
+ # response headers.
45
47
  class FileHandler
46
- # +Accept-Encoding+ value -> file extension
48
+ # `Accept-Encoding` value -> file extension
47
49
  PRECOMPRESSED = {
48
50
  "br" => ".br",
49
51
  "gzip" => ".gz",
50
52
  "identity" => nil
51
53
  }
52
54
 
53
- def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript)/)
55
+ def initialize(root, index: "index", headers: {}, precompressed: %i[ br gzip ], compressible_content_types: /\A(?:text\/|application\/javascript|image\/svg\+xml)/)
54
56
  @root = root.chomp("/").b
55
57
  @index = index
56
58
 
@@ -91,11 +93,11 @@ module ActionDispatch
91
93
 
92
94
  # Match a URI path to a static file to be served.
93
95
  #
94
- # Used by the +Static+ class to negotiate a servable file in the
95
- # +public/+ directory (see Static#call).
96
+ # Used by the `Static` class to negotiate a servable file in the `public/`
97
+ # directory (see Static#call).
96
98
  #
97
- # Checks for +path+, +path+.html, and +path+/index.html files,
98
- # in that order, including .br and .gzip compressed extensions.
99
+ # Checks for `path`, `path`.html, and `path`/index.html files, in that order,
100
+ # including .br and .gzip compressed extensions.
99
101
  #
100
102
  # If a matching file is found, the path and necessary response headers
101
103
  # (Content-Type, Content-Encoding) are returned.
@@ -120,11 +122,11 @@ module ActionDispatch
120
122
  def try_precompressed_files(filepath, headers, accept_encoding:)
121
123
  each_precompressed_filepath(filepath) do |content_encoding, precompressed_filepath|
122
124
  if file_readable? precompressed_filepath
123
- # Identity encoding is default, so we skip Accept-Encoding
124
- # negotiation and needn't set Content-Encoding.
125
+ # Identity encoding is default, so we skip Accept-Encoding negotiation and
126
+ # needn't set Content-Encoding.
125
127
  #
126
- # Vary header is expected when we've found other available
127
- # encodings that Accept-Encoding ruled out.
128
+ # Vary header is expected when we've found other available encodings that
129
+ # Accept-Encoding ruled out.
128
130
  if content_encoding == "identity"
129
131
  return precompressed_filepath, headers
130
132
  else
@@ -164,9 +166,9 @@ module ActionDispatch
164
166
  content_type = ::Rack::Mime.mime_type(ext, nil)
165
167
  yield path, content_type || "text/plain"
166
168
 
167
- # Tack on .html and /index.html only for paths that don't have
168
- # an explicit, resolvable file extension. No need to check
169
- # for foo.js.html and foo.js/index.html.
169
+ # Tack on .html and /index.html only for paths that don't have an explicit,
170
+ # resolvable file extension. No need to check for foo.js.html and
171
+ # foo.js/index.html.
170
172
  unless content_type
171
173
  default_ext = ::ActionController::Base.default_static_extension
172
174
  if ext != default_ext
@@ -29,7 +29,7 @@
29
29
  </table>
30
30
  </div>
31
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>
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
33
  <%- end -%>
34
34
  </div>
35
35
  <% end %>
@@ -11,7 +11,7 @@
11
11
  </p>
12
12
  <p>
13
13
  For example, a <code><%= @exception.controller %>#<%= @exception.action_name %></code> action defined in <code>app/controllers/<%= @exception.controller.controller_path %>_controller.rb</code> should have a corresponding view template
14
- in a file named <code>app/views/<%= @exception.controller.controller_name %>/<%= @exception.action_name %>.html.erb</code>.
14
+ in a file named <code>app/views/<%= @exception.controller.controller_path %>/<%= @exception.action_name %>.html.erb</code>.
15
15
  </p>
16
16
  <p>
17
17
  However, if this controller is an API endpoint responding with 204 (No Content), which does not require a view template because it doesn't serve an HTML response, then this error will occur when trying to access it with a browser. In this particular scenario, you can ignore this error.
@@ -158,7 +158,7 @@
158
158
  function buildTr(string) {
159
159
  var tr = document.createElement('tr');
160
160
  var th = document.createElement('th');
161
- th.setAttribute('colspan', 4);
161
+ th.setAttribute('colspan', 5);
162
162
  tr.appendChild(th);
163
163
  th.innerText = string;
164
164
  return tr;
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :markup: markdown
4
+
3
5
  require "action_dispatch"
4
6
  require "action_dispatch/log_subscriber"
5
7
  require "active_support/messages/rotation_configuration"
@@ -51,9 +53,6 @@ module ActionDispatch
51
53
 
52
54
  ActiveSupport.on_load(:action_dispatch_request) do
53
55
  self.ignore_accept_header = app.config.action_dispatch.ignore_accept_header
54
- unless app.config.action_dispatch.respond_to?(:return_only_request_media_type_on_content_type)
55
- self.return_only_media_type_on_content_type = app.config.action_dispatch.return_only_request_media_type_on_content_type
56
- end
57
56
  ActionDispatch::Request::Utils.perform_deep_munge = app.config.action_dispatch.perform_deep_munge
58
57
  end
59
58
 
@@ -69,7 +68,6 @@ module ActionDispatch
69
68
  ActionDispatch::Cookies::CookieJar.always_write_cookie = config.action_dispatch.always_write_cookie
70
69
 
71
70
  ActionDispatch::Routing::Mapper.route_source_locations = Rails.env.development?
72
- ActionDispatch::Routing::Mapper.backtrace_cleaner = Rails.backtrace_cleaner
73
71
 
74
72
  ActionDispatch.test_app = app
75
73
  end