actionpack 7.0.4.3 → 7.0.8.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +117 -1
- data/README.rdoc +2 -2
- data/lib/abstract_controller/helpers.rb +15 -11
- data/lib/abstract_controller/rendering.rb +9 -11
- data/lib/abstract_controller/translation.rb +25 -3
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/metal/basic_implicit_render.rb +3 -1
- data/lib/action_controller/metal/conditional_get.rb +121 -123
- data/lib/action_controller/metal/content_security_policy.rb +4 -4
- data/lib/action_controller/metal/data_streaming.rb +18 -18
- data/lib/action_controller/metal/etag_with_flash.rb +1 -1
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/http_authentication.rb +2 -1
- data/lib/action_controller/metal/live.rb +1 -1
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +20 -3
- data/lib/action_controller/metal/renderers.rb +2 -2
- data/lib/action_controller/metal/rendering.rb +114 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +5 -3
- data/lib/action_controller/metal/rescue.rb +4 -3
- data/lib/action_controller/metal/streaming.rb +1 -1
- data/lib/action_controller/metal/strong_parameters.rb +40 -63
- data/lib/action_controller/metal/url_for.rb +2 -4
- data/lib/action_controller/railtie.rb +2 -1
- data/lib/action_controller/renderer.rb +1 -20
- data/lib/action_dispatch/http/cache.rb +7 -7
- data/lib/action_dispatch/http/content_security_policy.rb +5 -1
- data/lib/action_dispatch/http/filter_parameters.rb +13 -28
- data/lib/action_dispatch/http/headers.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +0 -7
- data/lib/action_dispatch/http/request.rb +15 -16
- data/lib/action_dispatch/http/response.rb +0 -4
- data/lib/action_dispatch/http/upload.rb +13 -2
- data/lib/action_dispatch/middleware/cookies.rb +6 -6
- data/lib/action_dispatch/middleware/host_authorization.rb +12 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +4 -4
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/show_exceptions.rb +10 -7
- data/lib/action_dispatch/middleware/static.rb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +17 -8
- data/lib/action_dispatch/routing/mapper.rb +23 -0
- data/lib/action_dispatch/routing/url_for.rb +21 -21
- data/lib/action_dispatch/system_testing/browser.rb +1 -1
- data/lib/action_dispatch/system_testing/driver.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +1 -1
- data/lib/action_pack/gem_version.rb +2 -2
- metadata +17 -17
|
@@ -37,7 +37,6 @@ module ActionDispatch # :nodoc:
|
|
|
37
37
|
request = ActionDispatch::Request.new(env)
|
|
38
38
|
_, headers, _ = response = @app.call(env)
|
|
39
39
|
|
|
40
|
-
return response unless html_response?(headers)
|
|
41
40
|
return response if policy_present?(headers)
|
|
42
41
|
|
|
43
42
|
if policy = request.permissions_policy
|
|
@@ -52,12 +51,6 @@ module ActionDispatch # :nodoc:
|
|
|
52
51
|
end
|
|
53
52
|
|
|
54
53
|
private
|
|
55
|
-
def html_response?(headers)
|
|
56
|
-
if content_type = headers[CONTENT_TYPE]
|
|
57
|
-
/html/.match?(content_type)
|
|
58
|
-
end
|
|
59
|
-
end
|
|
60
|
-
|
|
61
54
|
def policy_present?(headers)
|
|
62
55
|
headers[POLICY]
|
|
63
56
|
end
|
|
@@ -107,22 +107,21 @@ module ActionDispatch
|
|
|
107
107
|
has_header? key
|
|
108
108
|
end
|
|
109
109
|
|
|
110
|
-
#
|
|
111
|
-
# Hypertext Transfer Protocol -- HTTP/1.1 (https://www.ietf.org/rfc/rfc2616.txt)
|
|
112
|
-
# HTTP Extensions for Distributed Authoring -- WEBDAV (https://www.ietf.org/rfc/rfc2518.txt)
|
|
113
|
-
# Versioning Extensions to WebDAV (https://www.ietf.org/rfc/rfc3253.txt)
|
|
114
|
-
# Ordered Collections Protocol (WebDAV) (https://www.ietf.org/rfc/rfc3648.txt)
|
|
115
|
-
# Web Distributed Authoring and Versioning (WebDAV) Access Control Protocol (https://www.ietf.org/rfc/rfc3744.txt)
|
|
116
|
-
# Web Distributed Authoring and Versioning (WebDAV) SEARCH (https://www.ietf.org/rfc/rfc5323.txt)
|
|
117
|
-
# Calendar Extensions to WebDAV (https://www.ietf.org/rfc/rfc4791.txt)
|
|
118
|
-
# PATCH Method for HTTP (https://www.ietf.org/rfc/rfc5789.txt)
|
|
110
|
+
# HTTP methods from {RFC 2616: Hypertext Transfer Protocol -- HTTP/1.1}[https://www.ietf.org/rfc/rfc2616.txt]
|
|
119
111
|
RFC2616 = %w(OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT)
|
|
112
|
+
# HTTP methods from {RFC 2518: HTTP Extensions for Distributed Authoring -- WEBDAV}[https://www.ietf.org/rfc/rfc2518.txt]
|
|
120
113
|
RFC2518 = %w(PROPFIND PROPPATCH MKCOL COPY MOVE LOCK UNLOCK)
|
|
114
|
+
# HTTP methods from {RFC 3253: Versioning Extensions to WebDAV}[https://www.ietf.org/rfc/rfc3253.txt]
|
|
121
115
|
RFC3253 = %w(VERSION-CONTROL REPORT CHECKOUT CHECKIN UNCHECKOUT MKWORKSPACE UPDATE LABEL MERGE BASELINE-CONTROL MKACTIVITY)
|
|
116
|
+
# HTTP methods from {RFC 3648: WebDAV Ordered Collections Protocol}[https://www.ietf.org/rfc/rfc3648.txt]
|
|
122
117
|
RFC3648 = %w(ORDERPATCH)
|
|
118
|
+
# HTTP methods from {RFC 3744: WebDAV Access Control Protocol}[https://www.ietf.org/rfc/rfc3744.txt]
|
|
123
119
|
RFC3744 = %w(ACL)
|
|
120
|
+
# HTTP methods from {RFC 5323: WebDAV SEARCH}[https://www.ietf.org/rfc/rfc5323.txt]
|
|
124
121
|
RFC5323 = %w(SEARCH)
|
|
122
|
+
# HTTP methods from {RFC 4791: Calendaring Extensions to WebDAV}[https://www.ietf.org/rfc/rfc4791.txt]
|
|
125
123
|
RFC4791 = %w(MKCALENDAR)
|
|
124
|
+
# HTTP methods from {RFC 5789: PATCH Method for HTTP}[https://www.ietf.org/rfc/rfc5789.txt]
|
|
126
125
|
RFC5789 = %w(PATCH)
|
|
127
126
|
|
|
128
127
|
HTTP_METHODS = RFC2616 + RFC2518 + RFC3253 + RFC3648 + RFC3744 + RFC5323 + RFC4791 + RFC5789
|
|
@@ -271,7 +270,7 @@ module ActionDispatch
|
|
|
271
270
|
super.to_i
|
|
272
271
|
end
|
|
273
272
|
|
|
274
|
-
# Returns true if the
|
|
273
|
+
# Returns true if the +X-Requested-With+ header contains "XMLHttpRequest"
|
|
275
274
|
# (case-insensitive), which may need to be manually added depending on the
|
|
276
275
|
# choice of JavaScript libraries and frameworks.
|
|
277
276
|
def xml_http_request?
|
|
@@ -297,7 +296,7 @@ module ActionDispatch
|
|
|
297
296
|
|
|
298
297
|
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
|
299
298
|
|
|
300
|
-
# Returns the unique request id, which is based on either the X-Request-Id header that can
|
|
299
|
+
# Returns the unique request id, which is based on either the +X-Request-Id+ header that can
|
|
301
300
|
# be generated by a firewall, load balancer, or web server, or by the RequestId middleware
|
|
302
301
|
# (which sets the +action_dispatch.request_id+ environment variable).
|
|
303
302
|
#
|
|
@@ -341,13 +340,13 @@ module ActionDispatch
|
|
|
341
340
|
end
|
|
342
341
|
|
|
343
342
|
# Determine whether the request body contains form-data by checking
|
|
344
|
-
# the request Content-Type for one of the media-types:
|
|
345
|
-
#
|
|
343
|
+
# the request +Content-Type+ for one of the media-types:
|
|
344
|
+
# +application/x-www-form-urlencoded+ or +multipart/form-data+. The
|
|
346
345
|
# list of form-data media types can be modified through the
|
|
347
346
|
# +FORM_DATA_MEDIA_TYPES+ array.
|
|
348
347
|
#
|
|
349
348
|
# A request body is not assumed to contain form-data when no
|
|
350
|
-
# Content-Type header is provided and the request_method is POST.
|
|
349
|
+
# +Content-Type+ header is provided and the request_method is POST.
|
|
351
350
|
def form_data?
|
|
352
351
|
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
|
353
352
|
end
|
|
@@ -379,7 +378,7 @@ module ActionDispatch
|
|
|
379
378
|
Request::Utils.check_param_encoding(rack_query_params)
|
|
380
379
|
set_header k, Request::Utils.normalize_encode_params(rack_query_params)
|
|
381
380
|
end
|
|
382
|
-
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
|
381
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError, Rack::QueryParser::ParamsTooDeepError => e
|
|
383
382
|
raise ActionController::BadRequest.new("Invalid query parameters: #{e.message}")
|
|
384
383
|
end
|
|
385
384
|
alias :query_parameters :GET
|
|
@@ -394,7 +393,7 @@ module ActionDispatch
|
|
|
394
393
|
Request::Utils.check_param_encoding(pr)
|
|
395
394
|
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
|
396
395
|
end
|
|
397
|
-
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
|
396
|
+
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError, Rack::QueryParser::ParamsTooDeepError, EOFError => e
|
|
398
397
|
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
|
|
399
398
|
end
|
|
400
399
|
alias :request_parameters :POST
|
|
@@ -28,6 +28,8 @@ module ActionDispatch
|
|
|
28
28
|
@tempfile = hash[:tempfile]
|
|
29
29
|
raise(ArgumentError, ":tempfile is required") unless @tempfile
|
|
30
30
|
|
|
31
|
+
@content_type = hash[:type]
|
|
32
|
+
|
|
31
33
|
if hash[:filename]
|
|
32
34
|
@original_filename = hash[:filename].dup
|
|
33
35
|
|
|
@@ -40,8 +42,17 @@ module ActionDispatch
|
|
|
40
42
|
@original_filename = nil
|
|
41
43
|
end
|
|
42
44
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
+
if hash[:head]
|
|
46
|
+
@headers = hash[:head].dup
|
|
47
|
+
|
|
48
|
+
begin
|
|
49
|
+
@headers.encode!(Encoding::UTF_8)
|
|
50
|
+
rescue EncodingError
|
|
51
|
+
@headers.force_encoding(Encoding::UTF_8)
|
|
52
|
+
end
|
|
53
|
+
else
|
|
54
|
+
@headers = nil
|
|
55
|
+
end
|
|
45
56
|
end
|
|
46
57
|
|
|
47
58
|
# Shortcut for +tempfile.read+.
|
|
@@ -95,7 +95,7 @@ module ActionDispatch
|
|
|
95
95
|
# Read and write data to cookies through ActionController::Base#cookies.
|
|
96
96
|
#
|
|
97
97
|
# When reading cookie data, the data is read from the HTTP request header, Cookie.
|
|
98
|
-
# When writing cookie data, the data is sent out in the HTTP response header, Set-Cookie
|
|
98
|
+
# When writing cookie data, the data is sent out in the HTTP response header, +Set-Cookie+.
|
|
99
99
|
#
|
|
100
100
|
# Examples of writing:
|
|
101
101
|
#
|
|
@@ -443,7 +443,7 @@ module ActionDispatch
|
|
|
443
443
|
|
|
444
444
|
if options[:domain] == :all || options[:domain] == "all"
|
|
445
445
|
cookie_domain = ""
|
|
446
|
-
dot_splitted_host = request.host.split(
|
|
446
|
+
dot_splitted_host = request.host.split(".", -1)
|
|
447
447
|
|
|
448
448
|
# Case where request.host is not an IP address or it's an invalid domain
|
|
449
449
|
# (ip confirms to the domain structure we expect so we explicitly check for ip)
|
|
@@ -453,10 +453,10 @@ module ActionDispatch
|
|
|
453
453
|
end
|
|
454
454
|
|
|
455
455
|
# If there is a provided tld length then we use it otherwise default domain.
|
|
456
|
-
if options[:tld_length].present?
|
|
456
|
+
if options[:tld_length].present?
|
|
457
457
|
# Case where the tld_length provided is valid
|
|
458
458
|
if dot_splitted_host.length >= options[:tld_length]
|
|
459
|
-
cookie_domain = dot_splitted_host.last(options[:tld_length]).join(
|
|
459
|
+
cookie_domain = dot_splitted_host.last(options[:tld_length]).join(".")
|
|
460
460
|
end
|
|
461
461
|
# Case where tld_length is not provided
|
|
462
462
|
else
|
|
@@ -465,7 +465,7 @@ module ActionDispatch
|
|
|
465
465
|
cookie_domain = dot_splitted_host.last(2).join(".")
|
|
466
466
|
# **.**, ***.** style TLDs like co.uk and com.au
|
|
467
467
|
else
|
|
468
|
-
cookie_domain = dot_splitted_host.last(3).join(
|
|
468
|
+
cookie_domain = dot_splitted_host.last(3).join(".")
|
|
469
469
|
end
|
|
470
470
|
end
|
|
471
471
|
|
|
@@ -683,7 +683,7 @@ module ActionDispatch
|
|
|
683
683
|
deserialize(name) do |rotate|
|
|
684
684
|
@encryptor.decrypt_and_verify(encrypted_message, on_rotation: rotate, purpose: purpose)
|
|
685
685
|
end
|
|
686
|
-
rescue ActiveSupport::MessageEncryptor::InvalidMessage, ActiveSupport::MessageVerifier::InvalidSignature
|
|
686
|
+
rescue ActiveSupport::MessageEncryptor::InvalidMessage, ActiveSupport::MessageVerifier::InvalidSignature, JSON::ParserError
|
|
687
687
|
nil
|
|
688
688
|
end
|
|
689
689
|
|
|
@@ -95,7 +95,7 @@ module ActionDispatch
|
|
|
95
95
|
def response_body(request)
|
|
96
96
|
return "" unless request.get_header("action_dispatch.show_detailed_exceptions")
|
|
97
97
|
|
|
98
|
-
template = DebugView.new(
|
|
98
|
+
template = DebugView.new(hosts: request.env["action_dispatch.blocked_hosts"])
|
|
99
99
|
template.render(template: "rescues/blocked_host", layout: "rescues/layout")
|
|
100
100
|
end
|
|
101
101
|
|
|
@@ -111,7 +111,7 @@ module ActionDispatch
|
|
|
111
111
|
|
|
112
112
|
return unless logger
|
|
113
113
|
|
|
114
|
-
logger.error("[#{self.class.name}] Blocked
|
|
114
|
+
logger.error("[#{self.class.name}] Blocked hosts: #{request.env["action_dispatch.blocked_hosts"].join(", ")}")
|
|
115
115
|
end
|
|
116
116
|
|
|
117
117
|
def available_logger(request)
|
|
@@ -131,21 +131,28 @@ module ActionDispatch
|
|
|
131
131
|
return @app.call(env) if @permissions.empty?
|
|
132
132
|
|
|
133
133
|
request = Request.new(env)
|
|
134
|
+
hosts = blocked_hosts(request)
|
|
134
135
|
|
|
135
|
-
if
|
|
136
|
+
if hosts.empty? || excluded?(request)
|
|
136
137
|
mark_as_authorized(request)
|
|
137
138
|
@app.call(env)
|
|
138
139
|
else
|
|
140
|
+
env["action_dispatch.blocked_hosts"] = hosts
|
|
139
141
|
@response_app.call(env)
|
|
140
142
|
end
|
|
141
143
|
end
|
|
142
144
|
|
|
143
145
|
private
|
|
144
|
-
def
|
|
146
|
+
def blocked_hosts(request)
|
|
147
|
+
hosts = []
|
|
148
|
+
|
|
145
149
|
origin_host = request.get_header("HTTP_HOST")
|
|
150
|
+
hosts << origin_host unless @permissions.allows?(origin_host)
|
|
151
|
+
|
|
146
152
|
forwarded_host = request.x_forwarded_host&.split(/,\s?/)&.last
|
|
153
|
+
hosts << forwarded_host unless forwarded_host.blank? || @permissions.allows?(forwarded_host)
|
|
147
154
|
|
|
148
|
-
|
|
155
|
+
hosts
|
|
149
156
|
end
|
|
150
157
|
|
|
151
158
|
def excluded?(request)
|
|
@@ -22,7 +22,7 @@ module ActionDispatch
|
|
|
22
22
|
# This middleware assumes that there is at least one proxy sitting around
|
|
23
23
|
# and setting headers with the client's remote IP address. If you don't use
|
|
24
24
|
# a proxy, because you are hosted on e.g. Heroku without SSL, any client can
|
|
25
|
-
# claim to have any IP address by setting the X-Forwarded-For header. If you
|
|
25
|
+
# claim to have any IP address by setting the +X-Forwarded-For+ header. If you
|
|
26
26
|
# care about that, then you need to explicitly drop or ignore those headers
|
|
27
27
|
# sometime before this middleware runs.
|
|
28
28
|
class RemoteIp
|
|
@@ -53,7 +53,7 @@ module ActionDispatch
|
|
|
53
53
|
#
|
|
54
54
|
# The +custom_proxies+ argument can take an enumerable which will be used
|
|
55
55
|
# instead of +TRUSTED_PROXIES+. Any proxy setup will put the value you
|
|
56
|
-
# want in the middle (or at the beginning) of the X-Forwarded-For list,
|
|
56
|
+
# want in the middle (or at the beginning) of the +X-Forwarded-For+ list,
|
|
57
57
|
# with your proxy servers after it. If your proxies aren't removed, pass
|
|
58
58
|
# them in via the +custom_proxies+ parameter. That way, the middleware will
|
|
59
59
|
# ignore those IP addresses, and return the one that you want.
|
|
@@ -110,9 +110,9 @@ module ActionDispatch
|
|
|
110
110
|
# REMOTE_ADDR will be correct if the request is made directly against the
|
|
111
111
|
# Ruby process, on e.g. Heroku. When the request is proxied by another
|
|
112
112
|
# server like HAProxy or NGINX, the IP address that made the original
|
|
113
|
-
# request will be put in an X-Forwarded-For header. If there are multiple
|
|
113
|
+
# request will be put in an +X-Forwarded-For+ header. If there are multiple
|
|
114
114
|
# proxies, that header may contain a list of IPs. Other proxy services
|
|
115
|
-
# set the Client-Ip header instead, so we check that too.
|
|
115
|
+
# set the +Client-Ip+ header instead, so we check that too.
|
|
116
116
|
#
|
|
117
117
|
# As discussed in {this post about Rails IP Spoofing}[https://blog.gingerlime.com/2012/rails-ip-spoofing-vulnerabilities-and-protection/],
|
|
118
118
|
# while the first IP in the list is likely to be the "originating" IP,
|
|
@@ -6,9 +6,9 @@ require "active_support/core_ext/string/access"
|
|
|
6
6
|
module ActionDispatch
|
|
7
7
|
# Makes a unique request id available to the +action_dispatch.request_id+ env variable (which is then accessible
|
|
8
8
|
# through ActionDispatch::Request#request_id or the alias ActionDispatch::Request#uuid) and sends
|
|
9
|
-
# the same id to the client via the X-Request-Id header.
|
|
9
|
+
# the same id to the client via the +X-Request-Id+ header.
|
|
10
10
|
#
|
|
11
|
-
# The unique request id is either based on the X-Request-Id header in the request, which would typically be generated
|
|
11
|
+
# The unique request id is either based on the +X-Request-Id+ header in the request, which would typically be generated
|
|
12
12
|
# by a firewall, load balancer, or the web server, or, if this header is not available, a random uuid. If the
|
|
13
13
|
# header is accepted from the outside world, we sanitize it to a max of 255 chars and alphanumeric and dashes only.
|
|
14
14
|
#
|
|
@@ -6,14 +6,17 @@ module ActionDispatch
|
|
|
6
6
|
# This middleware rescues any exception returned by the application
|
|
7
7
|
# and calls an exceptions app that will wrap it in a format for the end user.
|
|
8
8
|
#
|
|
9
|
-
# The exceptions app should be passed as parameter on initialization
|
|
10
|
-
#
|
|
11
|
-
# store the exception in env["action_dispatch.exception"]
|
|
12
|
-
# PATH_INFO to the exception status code and call the Rack app.
|
|
9
|
+
# The exceptions app should be passed as a parameter on initialization of
|
|
10
|
+
# +ShowExceptions+. Every time there is an exception, +ShowExceptions+ will
|
|
11
|
+
# store the exception in <tt>env["action_dispatch.exception"]</tt>, rewrite
|
|
12
|
+
# the +PATH_INFO+ to the exception status code and call the Rack app.
|
|
13
13
|
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
14
|
+
# In \Rails applications, the exceptions app can be configured with
|
|
15
|
+
# +config.exceptions_app+, which defaults to ActionDispatch::PublicExceptions.
|
|
16
|
+
#
|
|
17
|
+
# If the application returns an <tt>"X-Cascade" => "pass"</tt> response, this
|
|
18
|
+
# middleware will send an empty response as a result with the correct status
|
|
19
|
+
# code. If any exception happens inside the exceptions app, this middleware
|
|
17
20
|
# catches the exceptions and returns a failsafe response.
|
|
18
21
|
class ShowExceptions
|
|
19
22
|
def initialize(app, exceptions_app)
|
|
@@ -24,7 +24,7 @@ module ActionDispatch
|
|
|
24
24
|
end
|
|
25
25
|
end
|
|
26
26
|
|
|
27
|
-
# This endpoint serves static files from disk using Rack::File
|
|
27
|
+
# This endpoint serves static files from disk using +Rack::File+.
|
|
28
28
|
#
|
|
29
29
|
# URL paths are matched with static files according to expected
|
|
30
30
|
# conventions: +path+, +path+.html, +path+/index.html.
|
|
@@ -33,13 +33,13 @@ module ActionDispatch
|
|
|
33
33
|
# and gzip (.gz) files are supported. If +path+.br exists, this
|
|
34
34
|
# endpoint returns that file with a <tt>Content-Encoding: br</tt> header.
|
|
35
35
|
#
|
|
36
|
-
# If no matching file is found, this endpoint responds 404 Not Found
|
|
36
|
+
# If no matching file is found, this endpoint responds <tt>404 Not Found</tt>.
|
|
37
37
|
#
|
|
38
38
|
# Pass the +root+ directory to search for matching files, an optional
|
|
39
39
|
# <tt>index: "index"</tt> to change the default +path+/index.html, and optional
|
|
40
40
|
# additional response headers.
|
|
41
41
|
class FileHandler
|
|
42
|
-
# Accept-Encoding value -> file extension
|
|
42
|
+
# +Accept-Encoding+ value -> file extension
|
|
43
43
|
PRECOMPRESSED = {
|
|
44
44
|
"br" => ".br",
|
|
45
45
|
"gzip" => ".gz",
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
<header>
|
|
2
|
-
<h1>Blocked
|
|
2
|
+
<h1>Blocked hosts: <%= @hosts.join(", ") %></h1>
|
|
3
3
|
</header>
|
|
4
4
|
<main role="main" id="container">
|
|
5
|
-
<h2>To allow requests to
|
|
6
|
-
<pre>
|
|
5
|
+
<h2>To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:</h2>
|
|
6
|
+
<pre>
|
|
7
|
+
<% @hosts.each do |host| %>
|
|
8
|
+
config.hosts << "<%= host %>"
|
|
9
|
+
<% end %>
|
|
10
|
+
</pre>
|
|
7
11
|
<p>For more details view: <a href="https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization">the Host Authorization guide</a></p>
|
|
8
12
|
</main>
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
Blocked
|
|
1
|
+
Blocked hosts: <%= @hosts.join(", ") %>
|
|
2
2
|
|
|
3
|
-
To allow requests to
|
|
3
|
+
To allow requests to these hosts, make sure they are valid hostnames (containing only numbers, letters, dashes and dots), then add the following to your environment configuration:
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
<% @hosts.each do |host| %>
|
|
6
|
+
config.hosts << "<%= host %>"
|
|
7
|
+
<% end %>
|
|
6
8
|
|
|
7
9
|
For more details on host authorization view: https://guides.rubyonrails.org/configuring.html#actiondispatch-hostauthorization
|
|
@@ -102,9 +102,9 @@
|
|
|
102
102
|
// Enables path search functionality
|
|
103
103
|
function setupMatchPaths() {
|
|
104
104
|
// Check if there are any matched results in a section
|
|
105
|
-
function checkNoMatch(section,
|
|
105
|
+
function checkNoMatch(section, trElement) {
|
|
106
106
|
if (section.children.length <= 1) {
|
|
107
|
-
section.
|
|
107
|
+
section.appendChild(trElement);
|
|
108
108
|
}
|
|
109
109
|
}
|
|
110
110
|
|
|
@@ -145,21 +145,30 @@
|
|
|
145
145
|
}
|
|
146
146
|
}
|
|
147
147
|
|
|
148
|
+
function buildTr(string) {
|
|
149
|
+
var tr = document.createElement('tr');
|
|
150
|
+
var th = document.createElement('th');
|
|
151
|
+
th.setAttribute('colspan', 4);
|
|
152
|
+
tr.appendChild(th);
|
|
153
|
+
th.innerText = string;
|
|
154
|
+
return tr;
|
|
155
|
+
}
|
|
156
|
+
|
|
148
157
|
// On key press perform a search for matching paths
|
|
149
158
|
delayedKeyup(searchElem, function() {
|
|
150
159
|
var path = sanitizePath(searchElem.value),
|
|
151
|
-
defaultExactMatch = '
|
|
152
|
-
defaultFuzzyMatch = '
|
|
153
|
-
noExactMatch = '
|
|
154
|
-
noFuzzyMatch = '
|
|
160
|
+
defaultExactMatch = buildTr('Paths Matching (' + path + '):'),
|
|
161
|
+
defaultFuzzyMatch = buildTr('Paths Containing (' + path +'):'),
|
|
162
|
+
noExactMatch = buildTr('No Exact Matches Found'),
|
|
163
|
+
noFuzzyMatch = buildTr('No Fuzzy Matches Found');
|
|
155
164
|
|
|
156
165
|
if (!path)
|
|
157
166
|
return searchElem.onblur();
|
|
158
167
|
|
|
159
168
|
getJSON('/rails/info/routes?path=' + path, function(matches){
|
|
160
169
|
// Clear out results section
|
|
161
|
-
exactSection.
|
|
162
|
-
fuzzySection.
|
|
170
|
+
exactSection.replaceChildren(defaultExactMatch);
|
|
171
|
+
fuzzySection.replaceChildren(defaultFuzzyMatch);
|
|
163
172
|
|
|
164
173
|
// Display exact matches and fuzzy matches
|
|
165
174
|
pathElements.forEach(function(elem) {
|
|
@@ -1584,6 +1584,29 @@ module ActionDispatch
|
|
|
1584
1584
|
!parent_resource.singleton? && @scope[:shallow]
|
|
1585
1585
|
end
|
|
1586
1586
|
|
|
1587
|
+
# Loads another routes file with the given +name+ located inside the
|
|
1588
|
+
# +config/routes+ directory. In that file, you can use the normal
|
|
1589
|
+
# routing DSL, but <i>do not</i> surround it with a
|
|
1590
|
+
# +Rails.application.routes.draw+ block.
|
|
1591
|
+
#
|
|
1592
|
+
# # config/routes.rb
|
|
1593
|
+
# Rails.application.routes.draw do
|
|
1594
|
+
# draw :admin # Loads `config/routes/admin.rb`
|
|
1595
|
+
# draw "third_party/some_gem" # Loads `config/routes/third_party/some_gem.rb`
|
|
1596
|
+
# end
|
|
1597
|
+
#
|
|
1598
|
+
# # config/routes/admin.rb
|
|
1599
|
+
# namespace :admin do
|
|
1600
|
+
# resources :accounts
|
|
1601
|
+
# end
|
|
1602
|
+
#
|
|
1603
|
+
# # config/routes/third_party/some_gem.rb
|
|
1604
|
+
# mount SomeGem::Engine, at: "/some_gem"
|
|
1605
|
+
#
|
|
1606
|
+
# <b>CAUTION:</b> Use this feature with care. Having multiple routes
|
|
1607
|
+
# files can negatively impact discoverability and readability. For most
|
|
1608
|
+
# applications — even those with a few hundred routes — it's easier for
|
|
1609
|
+
# developers to have a single routes file.
|
|
1587
1610
|
def draw(name)
|
|
1588
1611
|
path = @draw_paths.find do |_path|
|
|
1589
1612
|
File.exist? "#{_path}/#{name}.rb"
|
|
@@ -6,16 +6,16 @@ module ActionDispatch
|
|
|
6
6
|
# is also possible: a URL can be generated from one of your routing definitions.
|
|
7
7
|
# URL generation functionality is centralized in this module.
|
|
8
8
|
#
|
|
9
|
-
# See ActionDispatch::Routing for general information about routing and routes.rb
|
|
9
|
+
# See ActionDispatch::Routing for general information about routing and <tt>config/routes.rb</tt>.
|
|
10
10
|
#
|
|
11
11
|
# <b>Tip:</b> If you need to generate URLs from your models or some other place,
|
|
12
|
-
# then
|
|
12
|
+
# then ActionDispatch::Routing::UrlFor is what you're looking for. Read on for
|
|
13
13
|
# an introduction. In general, this module should not be included on its own,
|
|
14
|
-
# as it is usually included by url_helpers (as in Rails.application.routes.url_helpers).
|
|
14
|
+
# as it is usually included by +url_helpers+ (as in <tt>Rails.application.routes.url_helpers</tt>).
|
|
15
15
|
#
|
|
16
16
|
# == URL generation from parameters
|
|
17
17
|
#
|
|
18
|
-
# As you may know, some functions, such as ActionController::Base#url_for
|
|
18
|
+
# As you may know, some functions, such as <tt>ActionController::Base#url_for</tt>
|
|
19
19
|
# and ActionView::Helpers::UrlHelper#link_to, can generate URLs given a set
|
|
20
20
|
# of parameters. For example, you've probably had the chance to write code
|
|
21
21
|
# like this in one of your views:
|
|
@@ -24,12 +24,12 @@ module ActionDispatch
|
|
|
24
24
|
# action: 'new', message: 'Welcome!') %>
|
|
25
25
|
# # => <a href="/users/new?message=Welcome%21">Click here</a>
|
|
26
26
|
#
|
|
27
|
-
# link_to
|
|
28
|
-
# actually use
|
|
29
|
-
# they use the
|
|
27
|
+
# +link_to+, and all other functions that require URL generation functionality,
|
|
28
|
+
# actually use ActionDispatch::Routing::UrlFor under the hood. And in particular,
|
|
29
|
+
# they use the ActionDispatch::Routing::UrlFor#url_for method. One can generate
|
|
30
30
|
# the same path as the above example by using the following code:
|
|
31
31
|
#
|
|
32
|
-
# include UrlFor
|
|
32
|
+
# include ActionDispatch::Routing::UrlFor
|
|
33
33
|
# url_for(controller: 'users',
|
|
34
34
|
# action: 'new',
|
|
35
35
|
# message: 'Welcome!',
|
|
@@ -48,17 +48,17 @@ module ActionDispatch
|
|
|
48
48
|
# host: 'www.example.com')
|
|
49
49
|
# # => "http://www.example.com/users/new?message=Welcome%21"
|
|
50
50
|
#
|
|
51
|
-
# By default, all controllers and views have access to a special version of url_for
|
|
52
|
-
# that already knows what the current hostname is. So if you use url_for in your
|
|
51
|
+
# By default, all controllers and views have access to a special version of +url_for+,
|
|
52
|
+
# that already knows what the current hostname is. So if you use +url_for+ in your
|
|
53
53
|
# controllers or your views, then you don't need to explicitly pass the <tt>:host</tt>
|
|
54
54
|
# argument.
|
|
55
55
|
#
|
|
56
|
-
# For convenience
|
|
57
|
-
#
|
|
58
|
-
#
|
|
59
|
-
# the +:host+
|
|
60
|
-
#
|
|
61
|
-
#
|
|
56
|
+
# For convenience, mailers also include ActionDispatch::Routing::UrlFor. So
|
|
57
|
+
# within mailers, you can use url_for. However, mailers cannot access
|
|
58
|
+
# incoming web requests in order to derive hostname information, so you have
|
|
59
|
+
# to provide the +:host+ option or set the default host using
|
|
60
|
+
# +default_url_options+. For more information on url_for in mailers see the
|
|
61
|
+
# ActionMailer::Base documentation.
|
|
62
62
|
#
|
|
63
63
|
#
|
|
64
64
|
# == URL generation for named routes
|
|
@@ -72,7 +72,7 @@ module ActionDispatch
|
|
|
72
72
|
# This generates, among other things, the method <tt>users_path</tt>. By default,
|
|
73
73
|
# this method is accessible from your controllers, views, and mailers. If you need
|
|
74
74
|
# to access this auto-generated method from other places (such as a model), then
|
|
75
|
-
# you can do that by including Rails.application.routes.url_helpers in your class:
|
|
75
|
+
# you can do that by including <tt>Rails.application.routes.url_helpers</tt> in your class:
|
|
76
76
|
#
|
|
77
77
|
# class User < ActiveRecord::Base
|
|
78
78
|
# include Rails.application.routes.url_helpers
|
|
@@ -115,11 +115,11 @@ module ActionDispatch
|
|
|
115
115
|
default_url_options
|
|
116
116
|
end
|
|
117
117
|
|
|
118
|
-
# Generate a URL based on the options provided, default_url_options
|
|
119
|
-
# routes defined in routes.rb
|
|
118
|
+
# Generate a URL based on the options provided, +default_url_options+, and the
|
|
119
|
+
# routes defined in <tt>config/routes.rb</tt>. The following options are supported:
|
|
120
120
|
#
|
|
121
121
|
# * <tt>:only_path</tt> - If true, the relative URL is returned. Defaults to +false+.
|
|
122
|
-
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to
|
|
122
|
+
# * <tt>:protocol</tt> - The protocol to connect to. Defaults to <tt>"http"</tt>.
|
|
123
123
|
# * <tt>:host</tt> - Specifies the host the link should be targeted at.
|
|
124
124
|
# If <tt>:only_path</tt> is false, this option must be
|
|
125
125
|
# provided either explicitly, or via +default_url_options+.
|
|
@@ -134,7 +134,7 @@ module ActionDispatch
|
|
|
134
134
|
# * <tt>:port</tt> - Optionally specify the port to connect to.
|
|
135
135
|
# * <tt>:anchor</tt> - An anchor name to be appended to the path.
|
|
136
136
|
# * <tt>:params</tt> - The query parameters to be appended to the path.
|
|
137
|
-
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in "/archive/2009/"
|
|
137
|
+
# * <tt>:trailing_slash</tt> - If true, adds a trailing slash, as in <tt>"/archive/2009/"</tt>.
|
|
138
138
|
# * <tt>:script_name</tt> - Specifies application path relative to domain root. If provided, prepends application path.
|
|
139
139
|
#
|
|
140
140
|
# Any other key (<tt>:controller</tt>, <tt>:action</tt>, etc.) given to
|
|
@@ -26,7 +26,7 @@ module ActionDispatch
|
|
|
26
26
|
yield options if block_given? && options
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
-
# driver_path can be configured as a proc.
|
|
29
|
+
# driver_path can be configured as a proc.
|
|
30
30
|
# proc to update web drivers. Running this proc early allows us to only
|
|
31
31
|
# update the webdriver once and avoid race conditions when using
|
|
32
32
|
# parallel tests.
|
|
@@ -20,7 +20,7 @@ module ActionDispatch
|
|
|
20
20
|
#
|
|
21
21
|
# You can also pass an explicit status number like <tt>assert_response(501)</tt>
|
|
22
22
|
# or its symbolic equivalent <tt>assert_response(:not_implemented)</tt>.
|
|
23
|
-
# See Rack::Utils::SYMBOL_TO_STATUS_CODE for a full list.
|
|
23
|
+
# See +Rack::Utils::SYMBOL_TO_STATUS_CODE+ for a full list.
|
|
24
24
|
#
|
|
25
25
|
# # Asserts that the response was a redirection
|
|
26
26
|
# assert_response :redirect
|