actionpack 7.0.5 → 7.1.3.4
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 +368 -315
- data/MIT-LICENSE +1 -1
- data/README.rdoc +4 -4
- data/lib/abstract_controller/base.rb +20 -11
- data/lib/abstract_controller/caching/fragments.rb +2 -0
- data/lib/abstract_controller/callbacks.rb +31 -6
- data/lib/abstract_controller/deprecator.rb +7 -0
- data/lib/abstract_controller/helpers.rb +68 -22
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -16
- data/lib/abstract_controller/rendering.rb +3 -3
- data/lib/abstract_controller/translation.rb +9 -6
- data/lib/abstract_controller/url_for.rb +2 -0
- data/lib/abstract_controller.rb +6 -0
- data/lib/action_controller/api.rb +5 -3
- data/lib/action_controller/base.rb +3 -17
- data/lib/action_controller/caching.rb +2 -0
- data/lib/action_controller/deprecator.rb +7 -0
- data/lib/action_controller/form_builder.rb +2 -0
- data/lib/action_controller/log_subscriber.rb +16 -4
- data/lib/action_controller/metal/content_security_policy.rb +1 -1
- data/lib/action_controller/metal/data_streaming.rb +2 -0
- data/lib/action_controller/metal/default_headers.rb +2 -0
- data/lib/action_controller/metal/etag_with_flash.rb +2 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +2 -0
- data/lib/action_controller/metal/exceptions.rb +8 -0
- data/lib/action_controller/metal/head.rb +8 -6
- data/lib/action_controller/metal/helpers.rb +3 -14
- data/lib/action_controller/metal/http_authentication.rb +17 -8
- data/lib/action_controller/metal/implicit_render.rb +5 -3
- data/lib/action_controller/metal/instrumentation.rb +8 -1
- data/lib/action_controller/metal/live.rb +24 -0
- data/lib/action_controller/metal/mime_responds.rb +2 -2
- data/lib/action_controller/metal/params_wrapper.rb +4 -2
- data/lib/action_controller/metal/permissions_policy.rb +1 -1
- data/lib/action_controller/metal/redirecting.rb +24 -7
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +0 -7
- data/lib/action_controller/metal/request_forgery_protection.rb +139 -50
- data/lib/action_controller/metal/rescue.rb +6 -3
- data/lib/action_controller/metal/streaming.rb +70 -30
- data/lib/action_controller/metal/strong_parameters.rb +158 -101
- data/lib/action_controller/metal/url_for.rb +7 -0
- data/lib/action_controller/metal.rb +79 -21
- data/lib/action_controller/railtie.rb +22 -9
- data/lib/action_controller/renderer.rb +98 -65
- data/lib/action_controller/test_case.rb +15 -5
- data/lib/action_controller.rb +8 -1
- data/lib/action_dispatch/constants.rb +32 -0
- data/lib/action_dispatch/deprecator.rb +7 -0
- data/lib/action_dispatch/http/cache.rb +1 -3
- data/lib/action_dispatch/http/content_security_policy.rb +9 -8
- data/lib/action_dispatch/http/filter_parameters.rb +11 -5
- data/lib/action_dispatch/http/headers.rb +2 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +22 -22
- data/lib/action_dispatch/http/mime_type.rb +35 -12
- data/lib/action_dispatch/http/mime_types.rb +3 -1
- data/lib/action_dispatch/http/parameters.rb +1 -1
- data/lib/action_dispatch/http/permissions_policy.rb +38 -23
- data/lib/action_dispatch/http/rack_cache.rb +2 -0
- data/lib/action_dispatch/http/request.rb +48 -14
- data/lib/action_dispatch/http/response.rb +80 -59
- data/lib/action_dispatch/http/upload.rb +2 -0
- data/lib/action_dispatch/journey/formatter.rb +8 -2
- data/lib/action_dispatch/journey/path/pattern.rb +14 -14
- data/lib/action_dispatch/journey/route.rb +3 -2
- data/lib/action_dispatch/journey/router.rb +9 -8
- data/lib/action_dispatch/journey/routes.rb +2 -2
- data/lib/action_dispatch/log_subscriber.rb +23 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +5 -6
- data/lib/action_dispatch/middleware/assume_ssl.rb +24 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -0
- data/lib/action_dispatch/middleware/cookies.rb +81 -98
- data/lib/action_dispatch/middleware/debug_exceptions.rb +26 -25
- data/lib/action_dispatch/middleware/debug_locks.rb +4 -1
- data/lib/action_dispatch/middleware/debug_view.rb +7 -2
- data/lib/action_dispatch/middleware/exception_wrapper.rb +186 -27
- data/lib/action_dispatch/middleware/executor.rb +1 -1
- data/lib/action_dispatch/middleware/flash.rb +7 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +18 -8
- data/lib/action_dispatch/middleware/public_exceptions.rb +5 -3
- data/lib/action_dispatch/middleware/reloader.rb +7 -5
- data/lib/action_dispatch/middleware/remote_ip.rb +17 -16
- data/lib/action_dispatch/middleware/request_id.rb +2 -0
- data/lib/action_dispatch/middleware/server_timing.rb +4 -4
- data/lib/action_dispatch/middleware/session/abstract_store.rb +5 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +2 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +11 -5
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +3 -1
- data/lib/action_dispatch/middleware/show_exceptions.rb +25 -18
- data/lib/action_dispatch/middleware/ssl.rb +18 -6
- data/lib/action_dispatch/middleware/stack.rb +7 -2
- data/lib/action_dispatch/middleware/static.rb +12 -8
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/_message_and_suggestions.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +8 -1
- 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/rescues/diagnostics.html.erb +7 -7
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +17 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +16 -12
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +3 -3
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +4 -4
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +46 -37
- data/lib/action_dispatch/railtie.rb +14 -4
- data/lib/action_dispatch/request/session.rb +16 -6
- data/lib/action_dispatch/request/utils.rb +8 -3
- data/lib/action_dispatch/routing/inspector.rb +54 -6
- data/lib/action_dispatch/routing/mapper.rb +35 -24
- data/lib/action_dispatch/routing/polymorphic_routes.rb +2 -0
- data/lib/action_dispatch/routing/redirection.rb +15 -6
- data/lib/action_dispatch/routing/route_set.rb +52 -22
- data/lib/action_dispatch/routing/routes_proxy.rb +10 -15
- data/lib/action_dispatch/routing/url_for.rb +5 -1
- data/lib/action_dispatch/routing.rb +7 -7
- data/lib/action_dispatch/system_test_case.rb +3 -3
- data/lib/action_dispatch/system_testing/browser.rb +20 -19
- data/lib/action_dispatch/system_testing/driver.rb +13 -21
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +27 -16
- data/lib/action_dispatch/testing/assertion_response.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +13 -6
- data/lib/action_dispatch/testing/assertions/routing.rb +67 -28
- data/lib/action_dispatch/testing/assertions.rb +3 -1
- data/lib/action_dispatch/testing/integration.rb +27 -17
- data/lib/action_dispatch/testing/request_encoder.rb +4 -1
- data/lib/action_dispatch/testing/test_process.rb +4 -3
- data/lib/action_dispatch/testing/test_request.rb +1 -1
- data/lib/action_dispatch/testing/test_response.rb +23 -9
- data/lib/action_dispatch.rb +37 -4
- data/lib/action_pack/gem_version.rb +4 -4
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_pack.rb +1 -1
- metadata +67 -31
@@ -6,23 +6,23 @@ require "action_dispatch/http/cache"
|
|
6
6
|
require "monitor"
|
7
7
|
|
8
8
|
module ActionDispatch # :nodoc:
|
9
|
+
# = Action Dispatch \Response
|
10
|
+
#
|
9
11
|
# Represents an HTTP response generated by a controller action. Use it to
|
10
12
|
# retrieve the current state of the response, or customize the response. It can
|
11
13
|
# either represent a real HTTP response (i.e. one that is meant to be sent
|
12
14
|
# back to the web browser) or a TestResponse (i.e. one that is generated
|
13
15
|
# from integration tests).
|
14
16
|
#
|
15
|
-
# \Response
|
16
|
-
#
|
17
|
-
# methods
|
18
|
-
#
|
19
|
-
# ActionControllerBase#headers instead of Response#headers.
|
17
|
+
# The \Response object for the current request is exposed on controllers as
|
18
|
+
# ActionController::Metal#response. ActionController::Metal also provides a
|
19
|
+
# few additional methods that delegate to attributes of the \Response such as
|
20
|
+
# ActionController::Metal#headers.
|
20
21
|
#
|
21
|
-
#
|
22
|
-
# more detail
|
23
|
-
#
|
24
|
-
#
|
25
|
-
# objects of type TestResponse (which are of course also of type \Response).
|
22
|
+
# Integration tests will likely also want to inspect responses in
|
23
|
+
# more detail. Methods such as Integration::RequestHelpers#get
|
24
|
+
# and Integration::RequestHelpers#post return instances of
|
25
|
+
# TestResponse (which inherits from \Response) for this purpose.
|
26
26
|
#
|
27
27
|
# For example, the following demo integration test prints the body of the
|
28
28
|
# controller response to the console:
|
@@ -34,41 +34,43 @@ module ActionDispatch # :nodoc:
|
|
34
34
|
# end
|
35
35
|
# end
|
36
36
|
class Response
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
raise ActionDispatch::IllegalStateError, "header already sent"
|
46
|
-
end
|
47
|
-
|
48
|
-
super
|
49
|
-
end
|
50
|
-
|
51
|
-
def merge(other)
|
52
|
-
self.class.new @response, __getobj__.merge(other)
|
53
|
-
end
|
54
|
-
|
55
|
-
def to_hash
|
56
|
-
__getobj__.dup
|
57
|
-
end
|
37
|
+
begin
|
38
|
+
# For `Rack::Headers` (Rack 3+):
|
39
|
+
require "rack/headers"
|
40
|
+
Headers = ::Rack::Headers
|
41
|
+
rescue LoadError
|
42
|
+
# For `Rack::Utils::HeaderHash`:
|
43
|
+
require "rack/utils"
|
44
|
+
Headers = ::Rack::Utils::HeaderHash
|
58
45
|
end
|
59
46
|
|
47
|
+
# To be deprecated:
|
48
|
+
Header = Headers
|
49
|
+
|
60
50
|
# The request that the response is responding to.
|
61
51
|
attr_accessor :request
|
62
52
|
|
63
53
|
# The HTTP status code.
|
64
54
|
attr_reader :status
|
65
55
|
|
66
|
-
#
|
67
|
-
|
56
|
+
# The headers for the response.
|
57
|
+
#
|
58
|
+
# header["Content-Type"] # => "text/plain"
|
59
|
+
# header["Content-Type"] = "application/json"
|
60
|
+
# header["Content-Type"] # => "application/json"
|
61
|
+
#
|
62
|
+
# Also aliased as +headers+.
|
63
|
+
#
|
64
|
+
# headers["Content-Type"] # => "text/plain"
|
65
|
+
# headers["Content-Type"] = "application/json"
|
66
|
+
# headers["Content-Type"] # => "application/json"
|
67
|
+
#
|
68
|
+
# Also aliased as +header+ for compatibility.
|
69
|
+
attr_reader :headers
|
68
70
|
|
69
|
-
alias_method :
|
71
|
+
alias_method :header, :headers
|
70
72
|
|
71
|
-
delegate :[], :[]=, to: :@
|
73
|
+
delegate :[], :[]=, to: :@headers
|
72
74
|
|
73
75
|
def each(&block)
|
74
76
|
sending!
|
@@ -79,7 +81,6 @@ module ActionDispatch # :nodoc:
|
|
79
81
|
|
80
82
|
CONTENT_TYPE = "Content-Type"
|
81
83
|
SET_COOKIE = "Set-Cookie"
|
82
|
-
LOCATION = "Location"
|
83
84
|
NO_CONTENT_CODES = [100, 101, 102, 103, 204, 205, 304]
|
84
85
|
|
85
86
|
cattr_accessor :default_charset, default: "utf-8"
|
@@ -102,6 +103,12 @@ module ActionDispatch # :nodoc:
|
|
102
103
|
@str_body = nil
|
103
104
|
end
|
104
105
|
|
106
|
+
def to_ary
|
107
|
+
@buf.respond_to?(:to_ary) ?
|
108
|
+
@buf.to_ary :
|
109
|
+
@buf.each
|
110
|
+
end
|
111
|
+
|
105
112
|
def body
|
106
113
|
@str_body ||= begin
|
107
114
|
buf = +""
|
@@ -117,6 +124,7 @@ module ActionDispatch # :nodoc:
|
|
117
124
|
@response.commit!
|
118
125
|
@buf.push string
|
119
126
|
end
|
127
|
+
alias_method :<<, :write
|
120
128
|
|
121
129
|
def each(&block)
|
122
130
|
if @str_body
|
@@ -146,9 +154,9 @@ module ActionDispatch # :nodoc:
|
|
146
154
|
end
|
147
155
|
end
|
148
156
|
|
149
|
-
def self.create(status = 200,
|
150
|
-
|
151
|
-
new status,
|
157
|
+
def self.create(status = 200, headers = {}, body = [], default_headers: self.default_headers)
|
158
|
+
headers = merge_default_headers(headers, default_headers)
|
159
|
+
new status, headers, body
|
152
160
|
end
|
153
161
|
|
154
162
|
def self.merge_default_headers(original, default)
|
@@ -158,10 +166,14 @@ module ActionDispatch # :nodoc:
|
|
158
166
|
# The underlying body, as a streamable object.
|
159
167
|
attr_reader :stream
|
160
168
|
|
161
|
-
def initialize(status = 200,
|
169
|
+
def initialize(status = 200, headers = nil, body = [])
|
162
170
|
super()
|
163
171
|
|
164
|
-
@
|
172
|
+
@headers = Headers.new
|
173
|
+
|
174
|
+
headers&.each do |key, value|
|
175
|
+
@headers[key] = value
|
176
|
+
end
|
165
177
|
|
166
178
|
self.body, self.status = body, status
|
167
179
|
|
@@ -175,10 +187,10 @@ module ActionDispatch # :nodoc:
|
|
175
187
|
yield self if block_given?
|
176
188
|
end
|
177
189
|
|
178
|
-
def has_header?(key); headers.key? key; end
|
179
|
-
def get_header(key); headers[key]; end
|
180
|
-
def set_header(key, v); headers[key] = v; end
|
181
|
-
def delete_header(key); headers.delete key; end
|
190
|
+
def has_header?(key); @headers.key? key; end
|
191
|
+
def get_header(key); @headers[key]; end
|
192
|
+
def set_header(key, v); @headers[key] = v; end
|
193
|
+
def delete_header(key); @headers.delete key; end
|
182
194
|
|
183
195
|
def await_commit
|
184
196
|
synchronize do
|
@@ -281,7 +293,7 @@ module ActionDispatch # :nodoc:
|
|
281
293
|
@status
|
282
294
|
end
|
283
295
|
|
284
|
-
# Returns a string to ensure compatibility with
|
296
|
+
# Returns a string to ensure compatibility with +Net::HTTPResponse+.
|
285
297
|
def code
|
286
298
|
@status.to_s
|
287
299
|
end
|
@@ -384,7 +396,7 @@ module ActionDispatch # :nodoc:
|
|
384
396
|
# status, headers, body = *response
|
385
397
|
def to_a
|
386
398
|
commit!
|
387
|
-
rack_response @status, @
|
399
|
+
rack_response @status, @headers.to_hash
|
388
400
|
end
|
389
401
|
alias prepare! to_a
|
390
402
|
|
@@ -451,8 +463,7 @@ module ActionDispatch # :nodoc:
|
|
451
463
|
# our last chance.
|
452
464
|
commit! unless committed?
|
453
465
|
|
454
|
-
|
455
|
-
request.commit_cookie_jar! unless committed?
|
466
|
+
@request.commit_cookie_jar! unless committed?
|
456
467
|
end
|
457
468
|
|
458
469
|
def build_buffer(response, body)
|
@@ -476,10 +487,6 @@ module ActionDispatch # :nodoc:
|
|
476
487
|
@response = response
|
477
488
|
end
|
478
489
|
|
479
|
-
def each(*args, &block)
|
480
|
-
@response.each(*args, &block)
|
481
|
-
end
|
482
|
-
|
483
490
|
def close
|
484
491
|
# Rack "close" maps to Response#abort, and *not* Response#close
|
485
492
|
# (which is used when the controller's finished writing)
|
@@ -490,14 +497,28 @@ module ActionDispatch # :nodoc:
|
|
490
497
|
@response.body
|
491
498
|
end
|
492
499
|
|
500
|
+
BODY_METHODS = { to_ary: true, each: true, call: true, to_path: true }
|
501
|
+
|
493
502
|
def respond_to?(method, include_private = false)
|
494
|
-
if method
|
503
|
+
if BODY_METHODS.key?(method)
|
495
504
|
@response.stream.respond_to?(method)
|
496
505
|
else
|
497
506
|
super
|
498
507
|
end
|
499
508
|
end
|
500
509
|
|
510
|
+
def to_ary
|
511
|
+
@response.stream.to_ary
|
512
|
+
end
|
513
|
+
|
514
|
+
def each(*args, &block)
|
515
|
+
@response.each(*args, &block)
|
516
|
+
end
|
517
|
+
|
518
|
+
def call(*arguments, &block)
|
519
|
+
@response.stream.call(*arguments, &block)
|
520
|
+
end
|
521
|
+
|
501
522
|
def to_path
|
502
523
|
@response.stream.to_path
|
503
524
|
end
|
@@ -505,16 +526,16 @@ module ActionDispatch # :nodoc:
|
|
505
526
|
|
506
527
|
def handle_no_content!
|
507
528
|
if NO_CONTENT_CODES.include?(@status)
|
508
|
-
@
|
509
|
-
@
|
529
|
+
@headers.delete CONTENT_TYPE
|
530
|
+
@headers.delete "Content-Length"
|
510
531
|
end
|
511
532
|
end
|
512
533
|
|
513
|
-
def rack_response(status,
|
534
|
+
def rack_response(status, headers)
|
514
535
|
if NO_CONTENT_CODES.include?(status)
|
515
|
-
[status,
|
536
|
+
[status, headers, []]
|
516
537
|
else
|
517
|
-
[status,
|
538
|
+
[status, headers, RackBody.new(self)]
|
518
539
|
end
|
519
540
|
end
|
520
541
|
end
|
@@ -57,6 +57,9 @@ module ActionDispatch
|
|
57
57
|
end
|
58
58
|
|
59
59
|
def generate(name, options, path_parameters)
|
60
|
+
original_options = options.dup
|
61
|
+
path_params = options.delete(:path_params) || {}
|
62
|
+
options = path_params.merge(options)
|
60
63
|
constraints = path_parameters.merge(options)
|
61
64
|
missing_keys = nil
|
62
65
|
|
@@ -70,8 +73,11 @@ module ActionDispatch
|
|
70
73
|
|
71
74
|
missing_keys = missing_keys(route, parameterized_parts)
|
72
75
|
next if missing_keys && !missing_keys.empty?
|
73
|
-
params = options.
|
74
|
-
|
76
|
+
params = options.delete_if do |key, _|
|
77
|
+
# top-level params' normal behavior of generating query_params
|
78
|
+
# should be preserved even if the same key is also a bind_param
|
79
|
+
parameterized_parts.key?(key) || route.defaults.key?(key) ||
|
80
|
+
(path_params.key?(key) && !original_options.key?(key))
|
75
81
|
end
|
76
82
|
|
77
83
|
defaults = route.defaults
|
@@ -183,22 +183,22 @@ module ActionDispatch
|
|
183
183
|
end
|
184
184
|
|
185
185
|
def offsets
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
186
|
+
@offsets ||= begin
|
187
|
+
offsets = [0]
|
188
|
+
|
189
|
+
spec.find_all(&:symbol?).each do |node|
|
190
|
+
node = node.to_sym
|
191
|
+
|
192
|
+
if @requirements.key?(node)
|
193
|
+
re = /#{Regexp.union(@requirements[node])}|/
|
194
|
+
offsets.push((re.match("").length - 1) + offsets.last)
|
195
|
+
else
|
196
|
+
offsets << offsets.last
|
197
|
+
end
|
198
198
|
end
|
199
|
-
end
|
200
199
|
|
201
|
-
|
200
|
+
offsets
|
201
|
+
end
|
202
202
|
end
|
203
203
|
end
|
204
204
|
end
|
@@ -5,7 +5,7 @@ module ActionDispatch
|
|
5
5
|
module Journey
|
6
6
|
class Route
|
7
7
|
attr_reader :app, :path, :defaults, :name, :precedence, :constraints,
|
8
|
-
:internal, :scope_options, :ast
|
8
|
+
:internal, :scope_options, :ast, :source_location
|
9
9
|
|
10
10
|
alias :conditions :constraints
|
11
11
|
|
@@ -53,7 +53,7 @@ module ActionDispatch
|
|
53
53
|
##
|
54
54
|
# +path+ is a path constraint.
|
55
55
|
# +constraints+ is a hash of constraints to be applied to this route.
|
56
|
-
def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], defaults: {}, request_method_match: nil, precedence: 0, scope_options: {}, internal: false)
|
56
|
+
def initialize(name:, app: nil, path:, constraints: {}, required_defaults: [], defaults: {}, request_method_match: nil, precedence: 0, scope_options: {}, internal: false, source_location: nil)
|
57
57
|
@name = name
|
58
58
|
@app = app
|
59
59
|
@path = path
|
@@ -69,6 +69,7 @@ module ActionDispatch
|
|
69
69
|
@path_formatter = @path.build_formatter
|
70
70
|
@scope_options = scope_options
|
71
71
|
@internal = internal
|
72
|
+
@source_location = source_location
|
72
73
|
|
73
74
|
@ast = @path.ast.root
|
74
75
|
@path.ast.route = self
|
@@ -29,7 +29,7 @@ module ActionDispatch
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def serve(req)
|
32
|
-
find_routes(req)
|
32
|
+
find_routes(req) do |match, parameters, route|
|
33
33
|
set_params = req.path_parameters
|
34
34
|
path_info = req.path_info
|
35
35
|
script_name = req.script_name
|
@@ -46,24 +46,25 @@ module ActionDispatch
|
|
46
46
|
}
|
47
47
|
|
48
48
|
req.path_parameters = tmp_params
|
49
|
+
req.route_uri_pattern = route.path.spec.to_s
|
49
50
|
|
50
|
-
|
51
|
+
_, headers, _ = response = route.app.serve(req)
|
51
52
|
|
52
|
-
if "pass" == headers[
|
53
|
+
if "pass" == headers[Constants::X_CASCADE]
|
53
54
|
req.script_name = script_name
|
54
55
|
req.path_info = path_info
|
55
56
|
req.path_parameters = set_params
|
56
57
|
next
|
57
58
|
end
|
58
59
|
|
59
|
-
return
|
60
|
+
return response
|
60
61
|
end
|
61
62
|
|
62
|
-
[404, {
|
63
|
+
[404, { Constants::X_CASCADE => "pass" }, ["Not Found"]]
|
63
64
|
end
|
64
65
|
|
65
66
|
def recognize(rails_req)
|
66
|
-
find_routes(rails_req)
|
67
|
+
find_routes(rails_req) do |match, parameters, route|
|
67
68
|
unless route.path.anchored
|
68
69
|
rails_req.script_name = match.to_s
|
69
70
|
rails_req.path_info = match.post_match
|
@@ -120,14 +121,14 @@ module ActionDispatch
|
|
120
121
|
|
121
122
|
routes.sort_by!(&:precedence)
|
122
123
|
|
123
|
-
routes.
|
124
|
+
routes.each { |r|
|
124
125
|
match_data = r.path.match(path_info)
|
125
126
|
path_parameters = {}
|
126
127
|
match_data.names.each_with_index { |name, i|
|
127
128
|
val = match_data[i + 1]
|
128
129
|
path_parameters[name.to_sym] = Utils.unescape_uri(val) if val
|
129
130
|
}
|
130
|
-
[match_data, path_parameters, r]
|
131
|
+
yield [match_data, path_parameters, r]
|
131
132
|
}
|
132
133
|
end
|
133
134
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
class LogSubscriber < ActiveSupport::LogSubscriber
|
5
|
+
def redirect(event)
|
6
|
+
payload = event.payload
|
7
|
+
|
8
|
+
info { "Redirected to #{payload[:location]}" }
|
9
|
+
|
10
|
+
info do
|
11
|
+
status = payload[:status]
|
12
|
+
|
13
|
+
message = +"Completed #{status} #{Rack::Utils::HTTP_STATUS_CODES[status]} in #{event.duration.round}ms"
|
14
|
+
message << "\n\n" if defined?(Rails.env) && Rails.env.development?
|
15
|
+
|
16
|
+
message
|
17
|
+
end
|
18
|
+
end
|
19
|
+
subscribe_log_level :redirect, :info
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
ActionDispatch::LogSubscriber.attach_to :action_dispatch
|
@@ -1,6 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "erb"
|
4
3
|
require "uri"
|
5
4
|
require "active_support/actionable_error"
|
6
5
|
|
@@ -30,15 +29,15 @@ module ActionDispatch
|
|
30
29
|
uri = URI.parse location
|
31
30
|
|
32
31
|
if uri.relative? || uri.scheme == "http" || uri.scheme == "https"
|
33
|
-
body = "
|
32
|
+
body = ""
|
34
33
|
else
|
35
|
-
return [400, {
|
34
|
+
return [400, { Rack::CONTENT_TYPE => "text/plain; charset=utf-8" }, ["Invalid redirection URI"]]
|
36
35
|
end
|
37
36
|
|
38
37
|
[302, {
|
39
|
-
|
40
|
-
|
41
|
-
|
38
|
+
Rack::CONTENT_TYPE => "text/html; charset=#{Response.default_charset}",
|
39
|
+
Rack::CONTENT_LENGTH => body.bytesize.to_s,
|
40
|
+
ActionDispatch::Constants::LOCATION => location,
|
42
41
|
}, [body]]
|
43
42
|
end
|
44
43
|
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
# = Action Dispatch \AssumeSSL
|
5
|
+
#
|
6
|
+
# When proxying through a load balancer that terminates SSL, the forwarded request will appear
|
7
|
+
# as though it's HTTP instead of HTTPS to the application. This makes redirects and cookie
|
8
|
+
# security target HTTP instead of HTTPS. This middleware makes the server assume that the
|
9
|
+
# proxy already terminated SSL, and that the request really is HTTPS.
|
10
|
+
class AssumeSSL
|
11
|
+
def initialize(app)
|
12
|
+
@app = app
|
13
|
+
end
|
14
|
+
|
15
|
+
def call(env)
|
16
|
+
env["HTTPS"] = "on"
|
17
|
+
env["HTTP_X_FORWARDED_PORT"] = "443"
|
18
|
+
env["HTTP_X_FORWARDED_PROTO"] = "https"
|
19
|
+
env["rack.url_scheme"] = "https"
|
20
|
+
|
21
|
+
@app.call(env)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|