actionpack 7.1.3.2 → 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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +70 -530
- data/lib/abstract_controller/asset_paths.rb +2 -0
- data/lib/abstract_controller/base.rb +102 -98
- data/lib/abstract_controller/caching/fragments.rb +50 -53
- data/lib/abstract_controller/caching.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +66 -64
- data/lib/abstract_controller/collector.rb +6 -6
- data/lib/abstract_controller/deprecator.rb +2 -0
- data/lib/abstract_controller/error.rb +2 -0
- data/lib/abstract_controller/helpers.rb +70 -85
- data/lib/abstract_controller/logger.rb +2 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/rendering.rb +13 -12
- data/lib/abstract_controller/translation.rb +11 -10
- data/lib/abstract_controller/url_for.rb +8 -6
- data/lib/abstract_controller.rb +2 -0
- data/lib/action_controller/api/api_rendering.rb +2 -0
- data/lib/action_controller/api.rb +74 -72
- data/lib/action_controller/base.rb +155 -117
- data/lib/action_controller/caching.rb +15 -12
- data/lib/action_controller/deprecator.rb +2 -0
- data/lib/action_controller/form_builder.rb +20 -17
- data/lib/action_controller/log_subscriber.rb +3 -1
- data/lib/action_controller/metal/allow_browser.rb +119 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +2 -0
- data/lib/action_controller/metal/conditional_get.rb +188 -174
- data/lib/action_controller/metal/content_security_policy.rb +25 -24
- data/lib/action_controller/metal/cookies.rb +4 -2
- data/lib/action_controller/metal/data_streaming.rb +64 -55
- data/lib/action_controller/metal/default_headers.rb +5 -3
- data/lib/action_controller/metal/etag_with_flash.rb +3 -1
- data/lib/action_controller/metal/etag_with_template_digest.rb +17 -15
- data/lib/action_controller/metal/exceptions.rb +11 -9
- data/lib/action_controller/metal/flash.rb +12 -10
- data/lib/action_controller/metal/head.rb +12 -10
- data/lib/action_controller/metal/helpers.rb +63 -55
- data/lib/action_controller/metal/http_authentication.rb +209 -201
- data/lib/action_controller/metal/implicit_render.rb +17 -15
- data/lib/action_controller/metal/instrumentation.rb +15 -12
- data/lib/action_controller/metal/live.rb +113 -107
- data/lib/action_controller/metal/logging.rb +6 -4
- data/lib/action_controller/metal/mime_responds.rb +151 -142
- data/lib/action_controller/metal/parameter_encoding.rb +34 -32
- data/lib/action_controller/metal/params_wrapper.rb +57 -59
- data/lib/action_controller/metal/permissions_policy.rb +13 -12
- data/lib/action_controller/metal/rate_limiting.rb +62 -0
- data/lib/action_controller/metal/redirecting.rb +108 -82
- data/lib/action_controller/metal/renderers.rb +50 -49
- data/lib/action_controller/metal/rendering.rb +103 -75
- data/lib/action_controller/metal/request_forgery_protection.rb +162 -133
- data/lib/action_controller/metal/rescue.rb +11 -9
- data/lib/action_controller/metal/streaming.rb +138 -136
- data/lib/action_controller/metal/strong_parameters.rb +525 -480
- data/lib/action_controller/metal/testing.rb +2 -0
- data/lib/action_controller/metal/url_for.rb +17 -15
- data/lib/action_controller/metal.rb +58 -57
- data/lib/action_controller/railtie.rb +3 -0
- data/lib/action_controller/railties/helpers.rb +2 -0
- data/lib/action_controller/renderer.rb +42 -36
- data/lib/action_controller/template_assertions.rb +4 -2
- data/lib/action_controller/test_case.rb +146 -126
- data/lib/action_controller.rb +10 -3
- data/lib/action_dispatch/constants.rb +2 -0
- data/lib/action_dispatch/deprecator.rb +2 -0
- data/lib/action_dispatch/http/cache.rb +27 -26
- data/lib/action_dispatch/http/content_disposition.rb +2 -0
- data/lib/action_dispatch/http/content_security_policy.rb +44 -38
- data/lib/action_dispatch/http/filter_parameters.rb +9 -5
- data/lib/action_dispatch/http/filter_redirect.rb +15 -1
- data/lib/action_dispatch/http/headers.rb +22 -22
- data/lib/action_dispatch/http/mime_negotiation.rb +30 -41
- data/lib/action_dispatch/http/mime_type.rb +29 -22
- data/lib/action_dispatch/http/mime_types.rb +2 -0
- data/lib/action_dispatch/http/parameters.rb +11 -9
- data/lib/action_dispatch/http/permissions_policy.rb +20 -37
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +71 -71
- data/lib/action_dispatch/http/response.rb +61 -61
- data/lib/action_dispatch/http/upload.rb +18 -16
- data/lib/action_dispatch/http/url.rb +75 -73
- data/lib/action_dispatch/journey/formatter.rb +13 -6
- data/lib/action_dispatch/journey/gtg/builder.rb +4 -3
- data/lib/action_dispatch/journey/gtg/simulator.rb +2 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +10 -8
- data/lib/action_dispatch/journey/nfa/dot.rb +2 -0
- data/lib/action_dispatch/journey/nodes/node.rb +6 -5
- data/lib/action_dispatch/journey/parser.rb +4 -3
- data/lib/action_dispatch/journey/parser_extras.rb +2 -0
- data/lib/action_dispatch/journey/path/pattern.rb +4 -1
- data/lib/action_dispatch/journey/route.rb +9 -7
- data/lib/action_dispatch/journey/router/utils.rb +16 -15
- data/lib/action_dispatch/journey/router.rb +4 -2
- data/lib/action_dispatch/journey/routes.rb +4 -2
- data/lib/action_dispatch/journey/scanner.rb +4 -2
- data/lib/action_dispatch/journey/visitors.rb +2 -0
- data/lib/action_dispatch/journey.rb +2 -0
- data/lib/action_dispatch/log_subscriber.rb +2 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +2 -0
- data/lib/action_dispatch/middleware/assume_ssl.rb +8 -5
- data/lib/action_dispatch/middleware/callbacks.rb +3 -1
- data/lib/action_dispatch/middleware/cookies.rb +119 -104
- data/lib/action_dispatch/middleware/debug_exceptions.rb +13 -5
- data/lib/action_dispatch/middleware/debug_locks.rb +15 -13
- data/lib/action_dispatch/middleware/debug_view.rb +2 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +6 -11
- data/lib/action_dispatch/middleware/executor.rb +8 -0
- data/lib/action_dispatch/middleware/flash.rb +63 -51
- data/lib/action_dispatch/middleware/host_authorization.rb +17 -15
- data/lib/action_dispatch/middleware/public_exceptions.rb +8 -6
- data/lib/action_dispatch/middleware/reloader.rb +5 -3
- data/lib/action_dispatch/middleware/remote_ip.rb +77 -72
- data/lib/action_dispatch/middleware/request_id.rb +14 -9
- data/lib/action_dispatch/middleware/server_timing.rb +4 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +13 -8
- data/lib/action_dispatch/middleware/session/cookie_store.rb +27 -26
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +7 -3
- data/lib/action_dispatch/middleware/show_exceptions.rb +31 -21
- data/lib/action_dispatch/middleware/ssl.rb +43 -40
- data/lib/action_dispatch/middleware/stack.rb +11 -10
- data/lib/action_dispatch/middleware/static.rb +33 -31
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +1 -1
- data/lib/action_dispatch/railtie.rb +2 -4
- data/lib/action_dispatch/request/session.rb +23 -21
- data/lib/action_dispatch/request/utils.rb +2 -0
- data/lib/action_dispatch/routing/endpoint.rb +2 -0
- data/lib/action_dispatch/routing/inspector.rb +5 -3
- data/lib/action_dispatch/routing/mapper.rb +670 -635
- data/lib/action_dispatch/routing/polymorphic_routes.rb +69 -62
- data/lib/action_dispatch/routing/redirection.rb +37 -32
- data/lib/action_dispatch/routing/route_set.rb +59 -45
- data/lib/action_dispatch/routing/routes_proxy.rb +6 -4
- data/lib/action_dispatch/routing/url_for.rb +130 -125
- data/lib/action_dispatch/routing.rb +150 -148
- data/lib/action_dispatch/system_test_case.rb +91 -81
- data/lib/action_dispatch/system_testing/browser.rb +10 -3
- data/lib/action_dispatch/system_testing/driver.rb +3 -1
- data/lib/action_dispatch/system_testing/server.rb +2 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +32 -21
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +2 -0
- data/lib/action_dispatch/testing/assertion_response.rb +8 -6
- data/lib/action_dispatch/testing/assertions/response.rb +26 -23
- data/lib/action_dispatch/testing/assertions/routing.rb +153 -84
- data/lib/action_dispatch/testing/assertions.rb +2 -0
- data/lib/action_dispatch/testing/integration.rb +223 -222
- data/lib/action_dispatch/testing/request_encoder.rb +2 -0
- data/lib/action_dispatch/testing/test_helpers/page_dump_helper.rb +35 -0
- data/lib/action_dispatch/testing/test_process.rb +12 -8
- data/lib/action_dispatch/testing/test_request.rb +3 -1
- data/lib/action_dispatch/testing/test_response.rb +27 -26
- data/lib/action_dispatch.rb +22 -28
- data/lib/action_pack/gem_version.rb +6 -4
- data/lib/action_pack/version.rb +3 -1
- data/lib/action_pack.rb +17 -16
- 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
|
-
#
|
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,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
|
-
#
|
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
|
-
#
|
10
|
-
#
|
11
|
-
#
|
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
|
-
#
|
11
|
+
# # Action Dispatch Session CookieStore
|
10
12
|
#
|
11
|
-
# This cookie-based session store is the
|
12
|
-
#
|
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
|
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
|
-
#
|
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
|
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
|
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
|
-
#
|
29
|
+
# Rails.application.config.session_store :cookie_store, key: '_your_app_session'
|
28
30
|
#
|
29
|
-
# In the development and test environments your application's
|
30
|
-
# generated by
|
31
|
-
# In all other environments, it is stored encrypted in
|
32
|
-
#
|
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
|
35
|
-
# will be found in the old
|
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
|
38
|
-
# Additionally, you should take care to make sure you are not relying
|
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
|
43
|
-
# options described there can be used to customize the session cookie that
|
44
|
-
#
|
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
|
-
#
|
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
|
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
|
-
#
|
15
|
+
# # Action Dispatch Session MemCacheStore
|
14
16
|
#
|
15
17
|
# A session store that uses MemCache to implement storage.
|
16
18
|
#
|
17
|
-
#
|
18
|
-
# *
|
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
|
-
#
|
8
|
+
# # Action Dispatch ShowExceptions
|
7
9
|
#
|
8
|
-
# This middleware rescues any exception returned by the application
|
9
|
-
#
|
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
|
-
#
|
13
|
-
# store the exception in
|
14
|
-
#
|
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
|
17
|
-
#
|
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
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
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
|
-
#
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
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
|
-
#
|
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
|
-
#
|
7
|
-
# the
|
8
|
-
#
|
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
|
-
#
|
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
|
-
#
|
20
|
+
# config.ssl_options = { redirect: { exclude: -> request { /healthcheck/.match?(request.path) } } }
|
17
21
|
#
|
18
|
-
#
|
22
|
+
# Cookies will not be flagged as secure for excluded requests.
|
19
23
|
#
|
20
|
-
#
|
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
|
-
#
|
23
|
-
#
|
24
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
33
|
-
#
|
34
|
-
#
|
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
|
-
#
|
37
|
-
#
|
38
|
-
#
|
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
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
#
|
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
|
-
#
|
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
|
-
#
|
9
|
+
# # Action Dispatch MiddlewareStack
|
8
10
|
#
|
9
|
-
# Read more about
|
10
|
-
# 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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
8
|
+
# # Action Dispatch Static
|
7
9
|
#
|
8
|
-
# This middleware serves static files from disk, if available.
|
9
|
-
#
|
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
|
12
|
-
#
|
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
|
-
#
|
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
|
-
#
|
31
|
+
# # Action Dispatch FileHandler
|
30
32
|
#
|
31
|
-
# This endpoint serves static files from disk using
|
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
|
-
#
|
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
|
-
#
|
38
|
-
#
|
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
|
42
|
+
# If no matching file is found, this endpoint responds `404 Not Found`.
|
41
43
|
#
|
42
|
-
# Pass the
|
43
|
-
#
|
44
|
-
#
|
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
|
-
#
|
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
|
95
|
-
#
|
96
|
+
# Used by the `Static` class to negotiate a servable file in the `public/`
|
97
|
+
# directory (see Static#call).
|
96
98
|
#
|
97
|
-
# Checks for
|
98
|
-
#
|
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
|
-
#
|
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
|
-
#
|
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
|
-
#
|
169
|
-
#
|
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
|
32
|
+
<p class="error_highlight_tip">Tip: You may want to add <code>gem "error_highlight", ">= 0.4.0"</code> into your Gemfile, which will display the fine-grained error location.</p>
|
33
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.
|
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',
|
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
|