actionpack 6.1.4.1 → 7.0.0.rc2
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 +191 -378
- data/MIT-LICENSE +1 -1
- data/README.rdoc +2 -3
- data/lib/abstract_controller/asset_paths.rb +1 -1
- data/lib/abstract_controller/base.rb +7 -21
- data/lib/abstract_controller/caching/fragments.rb +2 -2
- data/lib/abstract_controller/caching.rb +1 -1
- data/lib/abstract_controller/callbacks.rb +21 -7
- data/lib/abstract_controller/collector.rb +4 -2
- data/lib/abstract_controller/error.rb +1 -1
- data/lib/abstract_controller/helpers.rb +3 -2
- data/lib/abstract_controller/logger.rb +1 -1
- data/lib/abstract_controller/railties/routes_helpers.rb +2 -0
- data/lib/abstract_controller/translation.rb +3 -2
- data/lib/abstract_controller/url_for.rb +4 -6
- data/lib/action_controller/api.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +4 -3
- data/lib/action_controller/metal/conditional_get.rb +38 -1
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/cookies.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +5 -13
- data/lib/action_controller/metal/exceptions.rb +19 -30
- data/lib/action_controller/metal/flash.rb +6 -2
- data/lib/action_controller/metal/helpers.rb +1 -1
- data/lib/action_controller/metal/http_authentication.rb +17 -16
- data/lib/action_controller/metal/instrumentation.rb +57 -52
- data/lib/action_controller/metal/live.rb +42 -2
- data/lib/action_controller/metal/mime_responds.rb +3 -3
- data/lib/action_controller/metal/params_wrapper.rb +20 -11
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +86 -16
- data/lib/action_controller/metal/rendering.rb +7 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +64 -24
- data/lib/action_controller/metal/rescue.rb +1 -1
- data/lib/action_controller/metal/streaming.rb +1 -3
- data/lib/action_controller/metal/strong_parameters.rb +84 -47
- data/lib/action_controller/metal/testing.rb +0 -2
- data/lib/action_controller/metal.rb +7 -10
- data/lib/action_controller/railtie.rb +49 -6
- data/lib/action_controller/test_case.rb +19 -4
- data/lib/action_controller.rb +1 -5
- data/lib/action_dispatch/http/cache.rb +13 -6
- data/lib/action_dispatch/http/content_security_policy.rb +39 -35
- data/lib/action_dispatch/http/filter_parameters.rb +5 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +13 -3
- data/lib/action_dispatch/http/mime_type.rb +9 -11
- data/lib/action_dispatch/http/parameters.rb +4 -4
- data/lib/action_dispatch/http/permissions_policy.rb +1 -1
- data/lib/action_dispatch/http/request.rb +10 -19
- data/lib/action_dispatch/http/response.rb +1 -13
- data/lib/action_dispatch/http/url.rb +11 -19
- data/lib/action_dispatch/journey/gtg/builder.rb +11 -12
- data/lib/action_dispatch/journey/gtg/simulator.rb +10 -4
- data/lib/action_dispatch/journey/gtg/transition_table.rb +77 -21
- data/lib/action_dispatch/journey/nodes/node.rb +70 -5
- data/lib/action_dispatch/journey/path/pattern.rb +22 -13
- data/lib/action_dispatch/journey/route.rb +6 -13
- data/lib/action_dispatch/journey/router/utils.rb +2 -2
- data/lib/action_dispatch/journey/router.rb +1 -1
- data/lib/action_dispatch/journey/routes.rb +3 -3
- data/lib/action_dispatch/journey/visualizer/fsm.js +49 -24
- data/lib/action_dispatch/journey/visualizer/index.html.erb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +0 -1
- data/lib/action_dispatch/middleware/cookies.rb +8 -4
- data/lib/action_dispatch/middleware/debug_exceptions.rb +6 -4
- data/lib/action_dispatch/middleware/debug_locks.rb +3 -3
- data/lib/action_dispatch/middleware/exception_wrapper.rb +4 -0
- data/lib/action_dispatch/middleware/executor.rb +3 -0
- data/lib/action_dispatch/middleware/flash.rb +9 -11
- data/lib/action_dispatch/middleware/host_authorization.rb +44 -30
- data/lib/action_dispatch/middleware/remote_ip.rb +16 -4
- data/lib/action_dispatch/middleware/server_timing.rb +33 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +1 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +17 -9
- data/lib/action_dispatch/middleware/stack.rb +27 -9
- data/lib/action_dispatch/middleware/static.rb +2 -6
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +4 -11
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +4 -3
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +28 -18
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +5 -14
- data/lib/action_dispatch/railtie.rb +8 -2
- data/lib/action_dispatch/request/session.rb +43 -13
- data/lib/action_dispatch/routing/inspector.rb +1 -1
- data/lib/action_dispatch/routing/mapper.rb +54 -78
- data/lib/action_dispatch/routing/redirection.rb +0 -2
- data/lib/action_dispatch/routing/route_set.rb +14 -6
- data/lib/action_dispatch/routing/routes_proxy.rb +1 -1
- data/lib/action_dispatch/routing/url_for.rb +1 -2
- data/lib/action_dispatch/routing.rb +2 -2
- data/lib/action_dispatch/system_test_case.rb +12 -6
- data/lib/action_dispatch/system_testing/browser.rb +2 -12
- data/lib/action_dispatch/system_testing/driver.rb +35 -11
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +10 -6
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +0 -8
- data/lib/action_dispatch/testing/assertions.rb +2 -5
- data/lib/action_dispatch/testing/integration.rb +6 -8
- data/lib/action_dispatch/testing/test_process.rb +3 -26
- data/lib/action_dispatch.rb +2 -1
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack.rb +1 -1
- metadata +18 -16
@@ -31,7 +31,7 @@ module ActionController
|
|
31
31
|
|
32
32
|
# ActionController::TestCase will be deprecated and moved to a gem in the future.
|
33
33
|
# Please use ActionDispatch::IntegrationTest going forward.
|
34
|
-
class TestRequest < ActionDispatch::TestRequest
|
34
|
+
class TestRequest < ActionDispatch::TestRequest # :nodoc:
|
35
35
|
DEFAULT_ENV = ActionDispatch::TestRequest::DEFAULT_ENV.dup
|
36
36
|
DEFAULT_ENV.delete "PATH_INFO"
|
37
37
|
|
@@ -179,7 +179,7 @@ module ActionController
|
|
179
179
|
|
180
180
|
# Methods #destroy and #load! are overridden to avoid calling methods on the
|
181
181
|
# @store object, which does not exist for the TestSession class.
|
182
|
-
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash
|
182
|
+
class TestSession < Rack::Session::Abstract::PersistedSecure::SecureSessionHash # :nodoc:
|
183
183
|
DEFAULT_OPTIONS = Rack::Session::Abstract::Persisted::DEFAULT_OPTIONS
|
184
184
|
|
185
185
|
def initialize(session = {})
|
@@ -214,6 +214,10 @@ module ActionController
|
|
214
214
|
@data.fetch(key.to_s, *args, &block)
|
215
215
|
end
|
216
216
|
|
217
|
+
def enabled?
|
218
|
+
true
|
219
|
+
end
|
220
|
+
|
217
221
|
private
|
218
222
|
def load!
|
219
223
|
@id
|
@@ -329,6 +333,8 @@ module ActionController
|
|
329
333
|
#
|
330
334
|
# assert_redirected_to page_url(title: 'foo')
|
331
335
|
class TestCase < ActiveSupport::TestCase
|
336
|
+
singleton_class.attr_accessor :executor_around_each_request
|
337
|
+
|
332
338
|
module Behavior
|
333
339
|
extend ActiveSupport::Concern
|
334
340
|
include ActionDispatch::TestProcess
|
@@ -574,10 +580,19 @@ module ActionController
|
|
574
580
|
end
|
575
581
|
end
|
576
582
|
|
583
|
+
def wrap_execution(&block)
|
584
|
+
if ActionController::TestCase.executor_around_each_request && defined?(Rails.application) && Rails.application
|
585
|
+
Rails.application.executor.wrap(&block)
|
586
|
+
else
|
587
|
+
yield
|
588
|
+
end
|
589
|
+
end
|
590
|
+
|
577
591
|
def process_controller_response(action, cookies, xhr)
|
578
592
|
begin
|
579
593
|
@controller.recycle!
|
580
|
-
|
594
|
+
|
595
|
+
wrap_execution { @controller.dispatch(action, @request, @response) }
|
581
596
|
ensure
|
582
597
|
@request = @controller.request
|
583
598
|
@response = @controller.response
|
@@ -623,7 +638,7 @@ module ActionController
|
|
623
638
|
end
|
624
639
|
|
625
640
|
def check_required_ivars
|
626
|
-
#
|
641
|
+
# Check for required instance variables so we can give an
|
627
642
|
# understandable error message.
|
628
643
|
[:@routes, :@controller, :@request, :@response].each do |iv_name|
|
629
644
|
if !instance_variable_defined?(iv_name) || instance_variable_get(iv_name).nil?
|
data/lib/action_controller.rb
CHANGED
@@ -18,10 +18,6 @@ module ActionController
|
|
18
18
|
end
|
19
19
|
|
20
20
|
autoload_under "metal" do
|
21
|
-
eager_autoload do
|
22
|
-
autoload :Live
|
23
|
-
end
|
24
|
-
|
25
21
|
autoload :ConditionalGet
|
26
22
|
autoload :ContentSecurityPolicy
|
27
23
|
autoload :Cookies
|
@@ -37,6 +33,7 @@ module ActionController
|
|
37
33
|
autoload :BasicImplicitRender
|
38
34
|
autoload :ImplicitRender
|
39
35
|
autoload :Instrumentation
|
36
|
+
autoload :Live
|
40
37
|
autoload :Logging
|
41
38
|
autoload :MimeResponds
|
42
39
|
autoload :ParamsWrapper
|
@@ -65,5 +62,4 @@ require "active_support/core_ext/module/attribute_accessors"
|
|
65
62
|
require "active_support/core_ext/load_error"
|
66
63
|
require "active_support/core_ext/module/attr_internal"
|
67
64
|
require "active_support/core_ext/name_error"
|
68
|
-
require "active_support/core_ext/uri"
|
69
65
|
require "active_support/inflector"
|
@@ -187,13 +187,20 @@ module ActionDispatch
|
|
187
187
|
|
188
188
|
return if control.empty? && cache_control.empty? # Let middleware handle default behavior
|
189
189
|
|
190
|
-
if
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
190
|
+
if cache_control.any?
|
191
|
+
# Any caching directive coming from a controller overrides
|
192
|
+
# no-cache/no-store in the default Cache-Control header.
|
193
|
+
control.delete(:no_cache)
|
194
|
+
control.delete(:no_store)
|
195
195
|
|
196
|
-
|
196
|
+
if extras = control.delete(:extras)
|
197
|
+
cache_control[:extras] ||= []
|
198
|
+
cache_control[:extras] += extras
|
199
|
+
cache_control[:extras].uniq!
|
200
|
+
end
|
201
|
+
|
202
|
+
control.merge! cache_control
|
203
|
+
end
|
197
204
|
|
198
205
|
options = []
|
199
206
|
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
require "active_support/core_ext/object/deep_dup"
|
4
4
|
|
5
|
-
module ActionDispatch
|
5
|
+
module ActionDispatch # :nodoc:
|
6
6
|
class ContentSecurityPolicy
|
7
7
|
class Middleware
|
8
8
|
CONTENT_TYPE = "Content-Type"
|
@@ -106,43 +106,47 @@ module ActionDispatch #:nodoc:
|
|
106
106
|
end
|
107
107
|
|
108
108
|
MAPPINGS = {
|
109
|
-
self:
|
110
|
-
unsafe_eval:
|
111
|
-
unsafe_inline:
|
112
|
-
none:
|
113
|
-
http:
|
114
|
-
https:
|
115
|
-
data:
|
116
|
-
mediastream:
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
109
|
+
self: "'self'",
|
110
|
+
unsafe_eval: "'unsafe-eval'",
|
111
|
+
unsafe_inline: "'unsafe-inline'",
|
112
|
+
none: "'none'",
|
113
|
+
http: "http:",
|
114
|
+
https: "https:",
|
115
|
+
data: "data:",
|
116
|
+
mediastream: "mediastream:",
|
117
|
+
allow_duplicates: "'allow-duplicates'",
|
118
|
+
blob: "blob:",
|
119
|
+
filesystem: "filesystem:",
|
120
|
+
report_sample: "'report-sample'",
|
121
|
+
script: "'script'",
|
122
|
+
strict_dynamic: "'strict-dynamic'",
|
123
|
+
ws: "ws:",
|
124
|
+
wss: "wss:"
|
123
125
|
}.freeze
|
124
126
|
|
125
127
|
DIRECTIVES = {
|
126
|
-
base_uri:
|
127
|
-
child_src:
|
128
|
-
connect_src:
|
129
|
-
default_src:
|
130
|
-
font_src:
|
131
|
-
form_action:
|
132
|
-
frame_ancestors:
|
133
|
-
frame_src:
|
134
|
-
img_src:
|
135
|
-
manifest_src:
|
136
|
-
media_src:
|
137
|
-
object_src:
|
138
|
-
prefetch_src:
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
128
|
+
base_uri: "base-uri",
|
129
|
+
child_src: "child-src",
|
130
|
+
connect_src: "connect-src",
|
131
|
+
default_src: "default-src",
|
132
|
+
font_src: "font-src",
|
133
|
+
form_action: "form-action",
|
134
|
+
frame_ancestors: "frame-ancestors",
|
135
|
+
frame_src: "frame-src",
|
136
|
+
img_src: "img-src",
|
137
|
+
manifest_src: "manifest-src",
|
138
|
+
media_src: "media-src",
|
139
|
+
object_src: "object-src",
|
140
|
+
prefetch_src: "prefetch-src",
|
141
|
+
require_trusted_types_for: "require-trusted-types-for",
|
142
|
+
script_src: "script-src",
|
143
|
+
script_src_attr: "script-src-attr",
|
144
|
+
script_src_elem: "script-src-elem",
|
145
|
+
style_src: "style-src",
|
146
|
+
style_src_attr: "style-src-attr",
|
147
|
+
style_src_elem: "style-src-elem",
|
148
|
+
trusted_types: "trusted-types",
|
149
|
+
worker_src: "worker-src"
|
146
150
|
}.freeze
|
147
151
|
|
148
152
|
DEFAULT_NONCE_DIRECTIVES = %w[script-src style-src].freeze
|
@@ -18,6 +18,11 @@ module ActionDispatch
|
|
18
18
|
# env["action_dispatch.parameter_filter"] = [:foo, "bar"]
|
19
19
|
# => replaces the value to all keys matching /foo|bar/i with "[FILTERED]"
|
20
20
|
#
|
21
|
+
# env["action_dispatch.parameter_filter"] = [ /\Apin\z/i, /\Apin_/i ]
|
22
|
+
# => replaces the value for the exact (case-insensitive) key 'pin' and all
|
23
|
+
# (case-insensitive) keys beginning with 'pin_', with "[FILTERED]"
|
24
|
+
# Does not match keys with 'pin' as a substring, such as 'shipping_id'.
|
25
|
+
#
|
21
26
|
# env["action_dispatch.parameter_filter"] = [ "credit_card.code" ]
|
22
27
|
# => replaces { credit_card: {code: "xxxx"} } with "[FILTERED]", does not
|
23
28
|
# change { file: { code: "xxxx"} }
|
@@ -16,12 +16,13 @@ module ActionDispatch
|
|
16
16
|
|
17
17
|
included do
|
18
18
|
mattr_accessor :ignore_accept_header, default: false
|
19
|
+
cattr_accessor :return_only_media_type_on_content_type, default: false
|
19
20
|
end
|
20
21
|
|
21
22
|
# The MIME type of the HTTP request, such as Mime[:xml].
|
22
23
|
def content_mime_type
|
23
24
|
fetch_header("action_dispatch.request.content_type") do |k|
|
24
|
-
v = if get_header("CONTENT_TYPE") =~ /^([
|
25
|
+
v = if get_header("CONTENT_TYPE") =~ /^([^,;]*)/
|
25
26
|
Mime::Type.lookup($1.strip.downcase)
|
26
27
|
else
|
27
28
|
nil
|
@@ -33,7 +34,16 @@ module ActionDispatch
|
|
33
34
|
end
|
34
35
|
|
35
36
|
def content_type
|
36
|
-
|
37
|
+
if self.class.return_only_media_type_on_content_type
|
38
|
+
ActiveSupport::Deprecation.warn(
|
39
|
+
"Rails 7.1 will return Content-Type header without modification." \
|
40
|
+
" If you want just the MIME type, please use `#media_type` instead."
|
41
|
+
)
|
42
|
+
|
43
|
+
content_mime_type&.to_s
|
44
|
+
else
|
45
|
+
super
|
46
|
+
end
|
37
47
|
end
|
38
48
|
|
39
49
|
def has_content_type? # :nodoc:
|
@@ -92,7 +102,7 @@ module ActionDispatch
|
|
92
102
|
def variant=(variant)
|
93
103
|
variant = Array(variant)
|
94
104
|
|
95
|
-
if variant.all?
|
105
|
+
if variant.all?(Symbol)
|
96
106
|
@variant = ActiveSupport::ArrayInquirer.new(variant)
|
97
107
|
else
|
98
108
|
raise ArgumentError, "request.variant must be set to a Symbol or an Array of Symbols."
|
@@ -1,7 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require "singleton"
|
4
|
-
require "active_support/core_ext/symbol/starts_ends_with"
|
5
4
|
|
6
5
|
module Mime
|
7
6
|
class Mimes
|
@@ -14,8 +13,8 @@ module Mime
|
|
14
13
|
@symbols = []
|
15
14
|
end
|
16
15
|
|
17
|
-
def each
|
18
|
-
@mimes.each
|
16
|
+
def each(&block)
|
17
|
+
@mimes.each(&block)
|
19
18
|
end
|
20
19
|
|
21
20
|
def <<(type)
|
@@ -43,9 +42,9 @@ module Mime
|
|
43
42
|
Type.lookup_by_extension(type)
|
44
43
|
end
|
45
44
|
|
46
|
-
def fetch(type)
|
45
|
+
def fetch(type, &block)
|
47
46
|
return type if type.is_a?(Type)
|
48
|
-
EXTENSION_LOOKUP.fetch(type.to_s)
|
47
|
+
EXTENSION_LOOKUP.fetch(type.to_s, &block)
|
49
48
|
end
|
50
49
|
end
|
51
50
|
|
@@ -68,7 +67,7 @@ module Mime
|
|
68
67
|
@register_callbacks = []
|
69
68
|
|
70
69
|
# A simple helper class used in parsing the accept header.
|
71
|
-
class AcceptItem
|
70
|
+
class AcceptItem # :nodoc:
|
72
71
|
attr_accessor :index, :name, :q
|
73
72
|
alias :to_s :name
|
74
73
|
|
@@ -86,7 +85,7 @@ module Mime
|
|
86
85
|
end
|
87
86
|
end
|
88
87
|
|
89
|
-
class AcceptList
|
88
|
+
class AcceptList # :nodoc:
|
90
89
|
def self.sort!(list)
|
91
90
|
list.sort!
|
92
91
|
|
@@ -226,10 +225,9 @@ module Mime
|
|
226
225
|
attr_reader :hash
|
227
226
|
|
228
227
|
MIME_NAME = "[a-zA-Z0-9][a-zA-Z0-9#{Regexp.escape('!#$&-^_.+')}]{0,126}"
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>\s*#{MIME_PARAMETER}\s*)*)\z/
|
228
|
+
MIME_PARAMETER_VALUE = "#{Regexp.escape('"')}?#{MIME_NAME}#{Regexp.escape('"')}?"
|
229
|
+
MIME_PARAMETER = "\s*;\s*#{MIME_NAME}(?:=#{MIME_PARAMETER_VALUE})?"
|
230
|
+
MIME_REGEXP = /\A(?:\*\/\*|#{MIME_NAME}\/(?:\*|#{MIME_NAME})(?>#{MIME_PARAMETER})*\s*)\z/
|
233
231
|
|
234
232
|
class InvalidMimeType < StandardError; end
|
235
233
|
|
@@ -17,8 +17,8 @@ module ActionDispatch
|
|
17
17
|
# Raised when raw data from the request cannot be parsed by the parser
|
18
18
|
# defined for request's content MIME type.
|
19
19
|
class ParseError < StandardError
|
20
|
-
def initialize
|
21
|
-
super(
|
20
|
+
def initialize(message = $!.message)
|
21
|
+
super(message)
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
@@ -62,7 +62,7 @@ module ActionDispatch
|
|
62
62
|
end
|
63
63
|
alias :params :parameters
|
64
64
|
|
65
|
-
def path_parameters=(parameters)
|
65
|
+
def path_parameters=(parameters) # :nodoc:
|
66
66
|
delete_header("action_dispatch.request.parameters")
|
67
67
|
|
68
68
|
parameters = Request::Utils.set_binary_encoding(self, parameters, parameters[:controller], parameters[:action])
|
@@ -93,7 +93,7 @@ module ActionDispatch
|
|
93
93
|
strategy.call(raw_post)
|
94
94
|
rescue # JSON or Ruby code block errors.
|
95
95
|
log_parse_error_once
|
96
|
-
raise ParseError
|
96
|
+
raise ParseError, "Error occurred while parsing request parameters"
|
97
97
|
end
|
98
98
|
end
|
99
99
|
|
@@ -42,11 +42,8 @@ module ActionDispatch
|
|
42
42
|
HTTP_NEGOTIATE HTTP_PRAGMA HTTP_CLIENT_IP
|
43
43
|
HTTP_X_FORWARDED_FOR HTTP_ORIGIN HTTP_VERSION
|
44
44
|
HTTP_X_CSRF_TOKEN HTTP_X_REQUEST_ID HTTP_X_FORWARDED_HOST
|
45
|
-
SERVER_ADDR
|
46
45
|
].freeze
|
47
46
|
|
48
|
-
# TODO: Remove SERVER_ADDR when we remove support to Rack 2.1.
|
49
|
-
# See https://github.com/rack/rack/commit/c173b188d81ee437b588c1e046a1c9f031dea550
|
50
47
|
ENV_METHODS.each do |env|
|
51
48
|
class_eval <<-METHOD, __FILE__, __LINE__ + 1
|
52
49
|
# frozen_string_literal: true
|
@@ -90,7 +87,7 @@ module ActionDispatch
|
|
90
87
|
controller_param = name.underscore
|
91
88
|
const_name = controller_param.camelize << "Controller"
|
92
89
|
begin
|
93
|
-
|
90
|
+
const_name.constantize
|
94
91
|
rescue NameError => error
|
95
92
|
if error.missing_name == const_name || const_name.start_with?("#{error.missing_name}::")
|
96
93
|
raise MissingController.new(error.message, error.name)
|
@@ -165,7 +162,7 @@ module ActionDispatch
|
|
165
162
|
set_header(routes.env_key, name.dup)
|
166
163
|
end
|
167
164
|
|
168
|
-
def request_method=(request_method)
|
165
|
+
def request_method=(request_method) # :nodoc:
|
169
166
|
if check_method(request_method)
|
170
167
|
@request_method = set_header("REQUEST_METHOD", request_method)
|
171
168
|
end
|
@@ -266,7 +263,7 @@ module ActionDispatch
|
|
266
263
|
# # get "/articles"
|
267
264
|
# request.media_type # => "application/x-www-form-urlencoded"
|
268
265
|
def media_type
|
269
|
-
content_mime_type
|
266
|
+
content_mime_type&.to_s
|
270
267
|
end
|
271
268
|
|
272
269
|
# Returns the content length of the request as an integer.
|
@@ -355,21 +352,15 @@ module ActionDispatch
|
|
355
352
|
FORM_DATA_MEDIA_TYPES.include?(media_type)
|
356
353
|
end
|
357
354
|
|
358
|
-
def body_stream
|
355
|
+
def body_stream # :nodoc:
|
359
356
|
get_header("rack.input")
|
360
357
|
end
|
361
358
|
|
362
|
-
# TODO This should be broken apart into AD::Request::Session and probably
|
363
|
-
# be included by the session middleware.
|
364
359
|
def reset_session
|
365
|
-
|
366
|
-
session.destroy
|
367
|
-
else
|
368
|
-
self.session = {}
|
369
|
-
end
|
360
|
+
session.destroy
|
370
361
|
end
|
371
362
|
|
372
|
-
def session=(session)
|
363
|
+
def session=(session) # :nodoc:
|
373
364
|
Session.set self, session
|
374
365
|
end
|
375
366
|
|
@@ -434,10 +425,6 @@ module ActionDispatch
|
|
434
425
|
def commit_flash
|
435
426
|
end
|
436
427
|
|
437
|
-
def ssl?
|
438
|
-
super || scheme == "wss"
|
439
|
-
end
|
440
|
-
|
441
428
|
def inspect # :nodoc:
|
442
429
|
"#<#{self.class.name} #{method} #{original_url.dump} for #{remote_ip}>"
|
443
430
|
end
|
@@ -447,6 +434,10 @@ module ActionDispatch
|
|
447
434
|
HTTP_METHOD_LOOKUP[name] || raise(ActionController::UnknownHttpMethod, "#{name}, accepted HTTP methods are #{HTTP_METHODS[0...-1].join(', ')}, and #{HTTP_METHODS[-1]}")
|
448
435
|
name
|
449
436
|
end
|
437
|
+
|
438
|
+
def default_session
|
439
|
+
Session.disabled(self)
|
440
|
+
end
|
450
441
|
end
|
451
442
|
end
|
452
443
|
|
@@ -86,18 +86,6 @@ module ActionDispatch # :nodoc:
|
|
86
86
|
cattr_accessor :default_charset, default: "utf-8"
|
87
87
|
cattr_accessor :default_headers
|
88
88
|
|
89
|
-
def self.return_only_media_type_on_content_type=(*)
|
90
|
-
ActiveSupport::Deprecation.warn(
|
91
|
-
".return_only_media_type_on_content_type= is dreprecated with no replacement and will be removed in 6.2."
|
92
|
-
)
|
93
|
-
end
|
94
|
-
|
95
|
-
def self.return_only_media_type_on_content_type
|
96
|
-
ActiveSupport::Deprecation.warn(
|
97
|
-
".return_only_media_type_on_content_type is dreprecated with no replacement and will be removed in 6.2."
|
98
|
-
)
|
99
|
-
end
|
100
|
-
|
101
89
|
include Rack::Response::Helpers
|
102
90
|
# Aliasing these off because AD::Http::Cache::Response defines them.
|
103
91
|
alias :_cache_control :cache_control
|
@@ -336,7 +324,7 @@ module ActionDispatch # :nodoc:
|
|
336
324
|
# Avoid having to pass an open file handle as the response body.
|
337
325
|
# Rack::Sendfile will usually intercept the response and uses
|
338
326
|
# the path directly, so there is no reason to open the file.
|
339
|
-
class FileBody
|
327
|
+
class FileBody # :nodoc:
|
340
328
|
attr_reader :to_path
|
341
329
|
|
342
330
|
def initialize(path)
|
@@ -71,7 +71,8 @@ module ActionDispatch
|
|
71
71
|
path = options[:script_name].to_s.chomp("/")
|
72
72
|
path << options[:path] if options.key?(:path)
|
73
73
|
|
74
|
-
|
74
|
+
path = "/" if options[:trailing_slash] && path.blank?
|
75
|
+
|
75
76
|
add_params(path, options[:params]) if options.key?(:params)
|
76
77
|
add_anchor(path, options[:anchor]) if options.key?(:anchor)
|
77
78
|
|
@@ -101,14 +102,6 @@ module ActionDispatch
|
|
101
102
|
parts[0..-(tld_length + 2)]
|
102
103
|
end
|
103
104
|
|
104
|
-
def add_trailing_slash(path)
|
105
|
-
if path.include?("?")
|
106
|
-
path.sub!(/\?/, '/\&')
|
107
|
-
elsif !path.include?(".")
|
108
|
-
path.sub!(/[^\/]\z|\A\z/, '\&/')
|
109
|
-
end
|
110
|
-
end
|
111
|
-
|
112
105
|
def build_host_url(host, port, protocol, options, path)
|
113
106
|
if match = host.match(HOST_REGEXP)
|
114
107
|
protocol ||= match[1] unless protocol == false
|
@@ -222,7 +215,7 @@ module ActionDispatch
|
|
222
215
|
if forwarded = x_forwarded_host.presence
|
223
216
|
forwarded.split(/,\s?/).last
|
224
217
|
else
|
225
|
-
get_header("HTTP_HOST") || "#{server_name
|
218
|
+
get_header("HTTP_HOST") || "#{server_name}:#{get_header('SERVER_PORT')}"
|
226
219
|
end
|
227
220
|
end
|
228
221
|
|
@@ -258,12 +251,10 @@ module ActionDispatch
|
|
258
251
|
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
259
252
|
# req.port # => 8080
|
260
253
|
def port
|
261
|
-
@port ||=
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
standard_port
|
266
|
-
end
|
254
|
+
@port ||= if raw_host_with_port =~ /:(\d+)$/
|
255
|
+
$1.to_i
|
256
|
+
else
|
257
|
+
standard_port
|
267
258
|
end
|
268
259
|
end
|
269
260
|
|
@@ -272,9 +263,10 @@ module ActionDispatch
|
|
272
263
|
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
273
264
|
# req.standard_port # => 80
|
274
265
|
def standard_port
|
275
|
-
|
276
|
-
|
277
|
-
else
|
266
|
+
if "https://" == protocol
|
267
|
+
443
|
268
|
+
else
|
269
|
+
80
|
278
270
|
end
|
279
271
|
end
|
280
272
|
|
@@ -6,13 +6,13 @@ module ActionDispatch
|
|
6
6
|
module Journey # :nodoc:
|
7
7
|
module GTG # :nodoc:
|
8
8
|
class Builder # :nodoc:
|
9
|
-
|
9
|
+
DUMMY_END_NODE = Nodes::Dummy.new
|
10
10
|
|
11
11
|
attr_reader :root, :ast, :endpoints
|
12
12
|
|
13
13
|
def initialize(root)
|
14
14
|
@root = root
|
15
|
-
@ast = Nodes::Cat.new root,
|
15
|
+
@ast = Nodes::Cat.new root, DUMMY_END_NODE
|
16
16
|
@followpos = build_followpos
|
17
17
|
end
|
18
18
|
|
@@ -28,12 +28,12 @@ module ActionDispatch
|
|
28
28
|
marked[s] = true # mark s
|
29
29
|
|
30
30
|
s.group_by { |state| symbol(state) }.each do |sym, ps|
|
31
|
-
u = ps.flat_map { |l| @followpos[l] }
|
31
|
+
u = ps.flat_map { |l| @followpos[l] }.uniq
|
32
32
|
next if u.empty?
|
33
33
|
|
34
34
|
from = state_id[s]
|
35
35
|
|
36
|
-
if u.all? { |pos| pos ==
|
36
|
+
if u.all? { |pos| pos == DUMMY_END_NODE }
|
37
37
|
to = state_id[Object.new]
|
38
38
|
dtrans[from, to] = sym
|
39
39
|
dtrans.add_accepting(to)
|
@@ -43,9 +43,9 @@ module ActionDispatch
|
|
43
43
|
to = state_id[u]
|
44
44
|
dtrans[from, to] = sym
|
45
45
|
|
46
|
-
if u.include?(
|
46
|
+
if u.include?(DUMMY_END_NODE)
|
47
47
|
ps.each do |state|
|
48
|
-
if @followpos[state].include?(
|
48
|
+
if @followpos[state].include?(DUMMY_END_NODE)
|
49
49
|
dtrans.add_memo(to, state.memo)
|
50
50
|
end
|
51
51
|
end
|
@@ -66,7 +66,10 @@ module ActionDispatch
|
|
66
66
|
when Nodes::Group
|
67
67
|
true
|
68
68
|
when Nodes::Star
|
69
|
-
|
69
|
+
# the default star regex is /(.+)/ which is NOT nullable
|
70
|
+
# but since different constraints can be provided we must
|
71
|
+
# actually check if this is the case or not.
|
72
|
+
node.regexp.match?("")
|
70
73
|
when Nodes::Or
|
71
74
|
node.children.any? { |c| nullable?(c) }
|
72
75
|
when Nodes::Cat
|
@@ -104,7 +107,7 @@ module ActionDispatch
|
|
104
107
|
def lastpos(node)
|
105
108
|
case node
|
106
109
|
when Nodes::Star
|
107
|
-
|
110
|
+
lastpos(node.left)
|
108
111
|
when Nodes::Or
|
109
112
|
node.children.flat_map { |c| lastpos(c) }.tap(&:uniq!)
|
110
113
|
when Nodes::Cat
|
@@ -131,10 +134,6 @@ module ActionDispatch
|
|
131
134
|
lastpos(n.left).each do |i|
|
132
135
|
table[i] += firstpos(n.right)
|
133
136
|
end
|
134
|
-
when Nodes::Star
|
135
|
-
lastpos(n).each do |i|
|
136
|
-
table[i] += firstpos(n)
|
137
|
-
end
|
138
137
|
end
|
139
138
|
end
|
140
139
|
table
|
@@ -14,7 +14,7 @@ module ActionDispatch
|
|
14
14
|
end
|
15
15
|
|
16
16
|
class Simulator # :nodoc:
|
17
|
-
INITIAL_STATE = [0].freeze
|
17
|
+
INITIAL_STATE = [ [0, nil] ].freeze
|
18
18
|
|
19
19
|
attr_reader :tt
|
20
20
|
|
@@ -25,13 +25,19 @@ module ActionDispatch
|
|
25
25
|
def memos(string)
|
26
26
|
input = StringScanner.new(string)
|
27
27
|
state = INITIAL_STATE
|
28
|
+
start_index = 0
|
28
29
|
|
29
30
|
while sym = input.scan(%r([/.?]|[^/.?]+))
|
30
|
-
|
31
|
+
end_index = start_index + sym.length
|
32
|
+
|
33
|
+
state = tt.move(state, string, start_index, end_index)
|
34
|
+
|
35
|
+
start_index = end_index
|
31
36
|
end
|
32
37
|
|
33
|
-
acceptance_states = state.each_with_object([]) do |
|
34
|
-
|
38
|
+
acceptance_states = state.each_with_object([]) do |s_d, memos|
|
39
|
+
s, idx = s_d
|
40
|
+
memos.concat(tt.memo(s)) if idx.nil? && tt.accepting?(s)
|
35
41
|
end
|
36
42
|
|
37
43
|
acceptance_states.empty? ? yield : acceptance_states
|