actionpack 5.2.4 → 6.0.2.1
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 +200 -317
- data/MIT-LICENSE +1 -1
- data/README.rdoc +3 -2
- data/lib/abstract_controller/base.rb +4 -2
- data/lib/abstract_controller/caching/fragments.rb +6 -22
- data/lib/abstract_controller/callbacks.rb +12 -0
- data/lib/abstract_controller/collector.rb +1 -1
- data/lib/abstract_controller/helpers.rb +2 -2
- data/lib/abstract_controller/railties/routes_helpers.rb +1 -1
- data/lib/abstract_controller/translation.rb +1 -0
- data/lib/action_controller.rb +5 -1
- data/lib/action_controller/api.rb +2 -1
- data/lib/action_controller/base.rb +2 -7
- data/lib/action_controller/caching.rb +1 -1
- data/lib/action_controller/log_subscriber.rb +8 -5
- data/lib/action_controller/metal.rb +1 -1
- data/lib/action_controller/metal/basic_implicit_render.rb +1 -1
- data/lib/action_controller/metal/conditional_get.rb +9 -3
- data/lib/action_controller/metal/data_streaming.rb +5 -6
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +1 -1
- data/lib/action_controller/metal/exceptions.rb +23 -2
- data/lib/action_controller/metal/flash.rb +5 -5
- data/lib/action_controller/metal/force_ssl.rb +15 -56
- data/lib/action_controller/metal/head.rb +1 -1
- data/lib/action_controller/metal/helpers.rb +3 -4
- data/lib/action_controller/metal/http_authentication.rb +20 -21
- data/lib/action_controller/metal/implicit_render.rb +4 -14
- data/lib/action_controller/metal/instrumentation.rb +3 -5
- data/lib/action_controller/metal/live.rb +29 -27
- data/lib/action_controller/metal/mime_responds.rb +13 -2
- data/lib/action_controller/metal/params_wrapper.rb +17 -13
- data/lib/action_controller/metal/redirecting.rb +5 -5
- data/lib/action_controller/metal/renderers.rb +4 -4
- data/lib/action_controller/metal/rendering.rb +2 -2
- data/lib/action_controller/metal/request_forgery_protection.rb +23 -12
- data/lib/action_controller/metal/strong_parameters.rb +63 -44
- data/lib/action_controller/metal/url_for.rb +1 -1
- data/lib/action_controller/railties/helpers.rb +1 -1
- data/lib/action_controller/renderer.rb +16 -3
- data/lib/action_controller/template_assertions.rb +1 -1
- data/lib/action_controller/test_case.rb +2 -5
- data/lib/action_dispatch.rb +9 -6
- data/lib/action_dispatch/http/cache.rb +14 -10
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +28 -16
- data/lib/action_dispatch/http/filter_parameters.rb +8 -6
- data/lib/action_dispatch/http/filter_redirect.rb +1 -1
- data/lib/action_dispatch/http/headers.rb +1 -1
- data/lib/action_dispatch/http/mime_negotiation.rb +7 -5
- data/lib/action_dispatch/http/mime_type.rb +14 -6
- data/lib/action_dispatch/http/parameter_filter.rb +5 -79
- data/lib/action_dispatch/http/parameters.rb +13 -3
- data/lib/action_dispatch/http/request.rb +10 -13
- data/lib/action_dispatch/http/response.rb +40 -20
- data/lib/action_dispatch/http/upload.rb +9 -1
- data/lib/action_dispatch/http/url.rb +81 -81
- data/lib/action_dispatch/journey/formatter.rb +2 -2
- data/lib/action_dispatch/journey/nfa/simulator.rb +0 -2
- data/lib/action_dispatch/journey/nodes/node.rb +9 -8
- data/lib/action_dispatch/journey/path/pattern.rb +6 -2
- data/lib/action_dispatch/journey/route.rb +5 -4
- data/lib/action_dispatch/journey/router.rb +0 -3
- data/lib/action_dispatch/journey/router/utils.rb +10 -10
- data/lib/action_dispatch/journey/routes.rb +0 -1
- data/lib/action_dispatch/journey/scanner.rb +11 -4
- data/lib/action_dispatch/journey/visitors.rb +1 -1
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
- data/lib/action_dispatch/middleware/callbacks.rb +2 -4
- data/lib/action_dispatch/middleware/cookies.rb +52 -74
- data/lib/action_dispatch/middleware/debug_exceptions.rb +39 -59
- data/lib/action_dispatch/middleware/debug_locks.rb +5 -5
- data/lib/action_dispatch/middleware/debug_view.rb +68 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +49 -15
- data/lib/action_dispatch/middleware/flash.rb +1 -1
- data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +6 -2
- data/lib/action_dispatch/middleware/remote_ip.rb +9 -11
- data/lib/action_dispatch/middleware/request_id.rb +2 -2
- data/lib/action_dispatch/middleware/session/abstract_store.rb +14 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +11 -6
- data/lib/action_dispatch/middleware/session/cookie_store.rb +18 -13
- data/lib/action_dispatch/middleware/show_exceptions.rb +1 -1
- data/lib/action_dispatch/middleware/ssl.rb +8 -8
- data/lib/action_dispatch/middleware/stack.rb +33 -1
- data/lib/action_dispatch/middleware/static.rb +5 -6
- data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
- data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +3 -1
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +45 -35
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +26 -4
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +7 -4
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +4 -2
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +4 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +1 -1
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +2 -2
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +3 -0
- data/lib/action_dispatch/railtie.rb +7 -2
- data/lib/action_dispatch/request/session.rb +15 -1
- data/lib/action_dispatch/routing.rb +21 -20
- data/lib/action_dispatch/routing/inspector.rb +99 -50
- data/lib/action_dispatch/routing/mapper.rb +61 -39
- data/lib/action_dispatch/routing/polymorphic_routes.rb +3 -4
- data/lib/action_dispatch/routing/route_set.rb +24 -27
- data/lib/action_dispatch/routing/url_for.rb +1 -0
- data/lib/action_dispatch/system_test_case.rb +44 -5
- data/lib/action_dispatch/system_testing/browser.rb +38 -7
- data/lib/action_dispatch/system_testing/driver.rb +10 -1
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +6 -5
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +7 -6
- data/lib/action_dispatch/testing/assertions.rb +1 -1
- data/lib/action_dispatch/testing/assertions/response.rb +2 -3
- data/lib/action_dispatch/testing/assertions/routing.rb +15 -3
- data/lib/action_dispatch/testing/integration.rb +12 -5
- data/lib/action_dispatch/testing/request_encoder.rb +2 -2
- data/lib/action_dispatch/testing/test_process.rb +2 -2
- data/lib/action_dispatch/testing/test_response.rb +4 -32
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/gem_version.rb +4 -4
- metadata +34 -15
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +0 -26
@@ -111,13 +111,23 @@ module ActionDispatch
|
|
111
111
|
begin
|
112
112
|
strategy.call(raw_post)
|
113
113
|
rescue # JSON or Ruby code block errors.
|
114
|
-
|
115
|
-
my_logger.debug "Error occurred while parsing request parameters.\nContents:\n\n#{raw_post}"
|
116
|
-
|
114
|
+
log_parse_error_once
|
117
115
|
raise ParseError
|
118
116
|
end
|
119
117
|
end
|
120
118
|
|
119
|
+
def log_parse_error_once
|
120
|
+
@parse_error_logged ||= begin
|
121
|
+
parse_logger = logger || ActiveSupport::Logger.new($stderr)
|
122
|
+
parse_logger.debug <<~MSG.chomp
|
123
|
+
Error occurred while parsing request parameters.
|
124
|
+
Contents:
|
125
|
+
|
126
|
+
#{raw_post}
|
127
|
+
MSG
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
121
131
|
def params_parsers
|
122
132
|
ActionDispatch::Request.parameter_parsers
|
123
133
|
end
|
@@ -136,11 +136,11 @@ module ActionDispatch
|
|
136
136
|
end
|
137
137
|
|
138
138
|
def routes # :nodoc:
|
139
|
-
get_header("action_dispatch.routes"
|
139
|
+
get_header("action_dispatch.routes")
|
140
140
|
end
|
141
141
|
|
142
142
|
def routes=(routes) # :nodoc:
|
143
|
-
set_header("action_dispatch.routes"
|
143
|
+
set_header("action_dispatch.routes", routes)
|
144
144
|
end
|
145
145
|
|
146
146
|
def engine_script_name(_routes) # :nodoc:
|
@@ -158,11 +158,11 @@ module ActionDispatch
|
|
158
158
|
end
|
159
159
|
|
160
160
|
def controller_instance # :nodoc:
|
161
|
-
get_header("action_controller.instance"
|
161
|
+
get_header("action_controller.instance")
|
162
162
|
end
|
163
163
|
|
164
164
|
def controller_instance=(controller) # :nodoc:
|
165
|
-
set_header("action_controller.instance"
|
165
|
+
set_header("action_controller.instance", controller)
|
166
166
|
end
|
167
167
|
|
168
168
|
def http_auth_salt
|
@@ -173,7 +173,7 @@ module ActionDispatch
|
|
173
173
|
# We're treating `nil` as "unset", and we want the default setting to be
|
174
174
|
# `true`. This logic should be extracted to `env_config` and calculated
|
175
175
|
# once.
|
176
|
-
!(get_header("action_dispatch.show_exceptions"
|
176
|
+
!(get_header("action_dispatch.show_exceptions") == false)
|
177
177
|
end
|
178
178
|
|
179
179
|
# Returns a symbol form of the #request_method.
|
@@ -280,10 +280,10 @@ module ActionDispatch
|
|
280
280
|
end
|
281
281
|
|
282
282
|
def remote_ip=(remote_ip)
|
283
|
-
set_header "action_dispatch.remote_ip"
|
283
|
+
set_header "action_dispatch.remote_ip", remote_ip
|
284
284
|
end
|
285
285
|
|
286
|
-
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id"
|
286
|
+
ACTION_DISPATCH_REQUEST_ID = "action_dispatch.request_id" # :nodoc:
|
287
287
|
|
288
288
|
# Returns the unique request id, which is based on either the X-Request-Id header that can
|
289
289
|
# be generated by a firewall, load balancer, or web server or by the RequestId middleware
|
@@ -383,9 +383,6 @@ module ActionDispatch
|
|
383
383
|
end
|
384
384
|
self.request_parameters = Request::Utils.normalize_encode_params(pr)
|
385
385
|
end
|
386
|
-
rescue Http::Parameters::ParseError # one of the parse strategies blew up
|
387
|
-
self.request_parameters = Request::Utils.normalize_encode_params(super || {})
|
388
|
-
raise
|
389
386
|
rescue Rack::Utils::ParameterTypeError, Rack::Utils::InvalidParameterError => e
|
390
387
|
raise ActionController::BadRequest.new("Invalid request parameters: #{e.message}")
|
391
388
|
end
|
@@ -407,18 +404,18 @@ module ActionDispatch
|
|
407
404
|
|
408
405
|
def request_parameters=(params)
|
409
406
|
raise if params.nil?
|
410
|
-
set_header("action_dispatch.request.request_parameters"
|
407
|
+
set_header("action_dispatch.request.request_parameters", params)
|
411
408
|
end
|
412
409
|
|
413
410
|
def logger
|
414
|
-
get_header("action_dispatch.logger"
|
411
|
+
get_header("action_dispatch.logger")
|
415
412
|
end
|
416
413
|
|
417
414
|
def commit_flash
|
418
415
|
end
|
419
416
|
|
420
417
|
def ssl?
|
421
|
-
super || scheme == "wss"
|
418
|
+
super || scheme == "wss"
|
422
419
|
end
|
423
420
|
|
424
421
|
private
|
@@ -78,13 +78,14 @@ module ActionDispatch # :nodoc:
|
|
78
78
|
x
|
79
79
|
end
|
80
80
|
|
81
|
-
CONTENT_TYPE = "Content-Type"
|
82
|
-
SET_COOKIE = "Set-Cookie"
|
83
|
-
LOCATION = "Location"
|
81
|
+
CONTENT_TYPE = "Content-Type"
|
82
|
+
SET_COOKIE = "Set-Cookie"
|
83
|
+
LOCATION = "Location"
|
84
84
|
NO_CONTENT_CODES = [100, 101, 102, 204, 205, 304]
|
85
85
|
|
86
86
|
cattr_accessor :default_charset, default: "utf-8"
|
87
87
|
cattr_accessor :default_headers
|
88
|
+
cattr_accessor :return_only_media_type_on_content_type, default: false
|
88
89
|
|
89
90
|
include Rack::Response::Helpers
|
90
91
|
# Aliasing these off because AD::Http::Cache::Response defines them.
|
@@ -105,7 +106,7 @@ module ActionDispatch # :nodoc:
|
|
105
106
|
|
106
107
|
def body
|
107
108
|
@str_body ||= begin
|
108
|
-
buf = ""
|
109
|
+
buf = +""
|
109
110
|
each { |chunk| buf << chunk }
|
110
111
|
buf
|
111
112
|
end
|
@@ -224,16 +225,6 @@ module ActionDispatch # :nodoc:
|
|
224
225
|
@status = Rack::Utils.status_code(status)
|
225
226
|
end
|
226
227
|
|
227
|
-
# Sets the HTTP content type.
|
228
|
-
def content_type=(content_type)
|
229
|
-
return unless content_type
|
230
|
-
new_header_info = parse_content_type(content_type.to_s)
|
231
|
-
prev_header_info = parsed_content_type_header
|
232
|
-
charset = new_header_info.charset || prev_header_info.charset
|
233
|
-
charset ||= self.class.default_charset unless prev_header_info.mime_type
|
234
|
-
set_content_type new_header_info.mime_type, charset
|
235
|
-
end
|
236
|
-
|
237
228
|
# Sets the HTTP response's content MIME type. For example, in the controller
|
238
229
|
# you could write this:
|
239
230
|
#
|
@@ -242,8 +233,32 @@ module ActionDispatch # :nodoc:
|
|
242
233
|
# If a character set has been defined for this response (see charset=) then
|
243
234
|
# the character set information will also be included in the content type
|
244
235
|
# information.
|
236
|
+
def content_type=(content_type)
|
237
|
+
return unless content_type
|
238
|
+
new_header_info = parse_content_type(content_type.to_s)
|
239
|
+
prev_header_info = parsed_content_type_header
|
240
|
+
charset = new_header_info.charset || prev_header_info.charset
|
241
|
+
charset ||= self.class.default_charset unless prev_header_info.mime_type
|
242
|
+
set_content_type new_header_info.mime_type, charset
|
243
|
+
end
|
245
244
|
|
245
|
+
# Content type of response.
|
246
246
|
def content_type
|
247
|
+
if self.class.return_only_media_type_on_content_type
|
248
|
+
ActiveSupport::Deprecation.warn(
|
249
|
+
"Rails 6.1 will return Content-Type header without modification." \
|
250
|
+
" If you want just the MIME type, please use `#media_type` instead."
|
251
|
+
)
|
252
|
+
|
253
|
+
content_type = super
|
254
|
+
content_type ? content_type.split(/;\s*charset=/)[0].presence : content_type
|
255
|
+
else
|
256
|
+
super.presence
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
# Media type of response.
|
261
|
+
def media_type
|
247
262
|
parsed_content_type_header.mime_type
|
248
263
|
end
|
249
264
|
|
@@ -404,15 +419,18 @@ module ActionDispatch # :nodoc:
|
|
404
419
|
end
|
405
420
|
|
406
421
|
private
|
407
|
-
|
408
422
|
ContentTypeHeader = Struct.new :mime_type, :charset
|
409
423
|
NullContentTypeHeader = ContentTypeHeader.new nil, nil
|
410
424
|
|
425
|
+
CONTENT_TYPE_PARSER = /
|
426
|
+
\A
|
427
|
+
(?<mime_type>[^;\s]+\s*(?:;\s*(?:(?!charset)[^;\s])+)*)?
|
428
|
+
(?:;\s*charset=(?<quote>"?)(?<charset>[^;\s]+)\k<quote>)?
|
429
|
+
/x # :nodoc:
|
430
|
+
|
411
431
|
def parse_content_type(content_type)
|
412
|
-
if content_type
|
413
|
-
|
414
|
-
type = nil if type && type.empty?
|
415
|
-
ContentTypeHeader.new(type, charset)
|
432
|
+
if content_type && match = CONTENT_TYPE_PARSER.match(content_type)
|
433
|
+
ContentTypeHeader.new(match[:mime_type], match[:charset])
|
416
434
|
else
|
417
435
|
NullContentTypeHeader
|
418
436
|
end
|
@@ -459,7 +477,7 @@ module ActionDispatch # :nodoc:
|
|
459
477
|
end
|
460
478
|
|
461
479
|
def assign_default_content_type_and_charset!
|
462
|
-
return if
|
480
|
+
return if media_type
|
463
481
|
|
464
482
|
ct = parsed_content_type_header
|
465
483
|
set_content_type(ct.mime_type || Mime[:html].to_s,
|
@@ -517,4 +535,6 @@ module ActionDispatch # :nodoc:
|
|
517
535
|
end
|
518
536
|
end
|
519
537
|
end
|
538
|
+
|
539
|
+
ActiveSupport.run_load_hooks(:action_dispatch_response, Response)
|
520
540
|
end
|
@@ -20,7 +20,6 @@ module ActionDispatch
|
|
20
20
|
# A +Tempfile+ object with the actual uploaded file. Note that some of
|
21
21
|
# its interface is available directly.
|
22
22
|
attr_accessor :tempfile
|
23
|
-
alias :to_io :tempfile
|
24
23
|
|
25
24
|
# A string with the headers of the multipart request.
|
26
25
|
attr_accessor :headers
|
@@ -65,6 +64,11 @@ module ActionDispatch
|
|
65
64
|
@tempfile.path
|
66
65
|
end
|
67
66
|
|
67
|
+
# Shortcut for +tempfile.to_path+.
|
68
|
+
def to_path
|
69
|
+
@tempfile.to_path
|
70
|
+
end
|
71
|
+
|
68
72
|
# Shortcut for +tempfile.rewind+.
|
69
73
|
def rewind
|
70
74
|
@tempfile.rewind
|
@@ -79,6 +83,10 @@ module ActionDispatch
|
|
79
83
|
def eof?
|
80
84
|
@tempfile.eof?
|
81
85
|
end
|
86
|
+
|
87
|
+
def to_io
|
88
|
+
@tempfile.to_io
|
89
|
+
end
|
82
90
|
end
|
83
91
|
end
|
84
92
|
end
|
@@ -67,7 +67,7 @@ module ActionDispatch
|
|
67
67
|
end
|
68
68
|
|
69
69
|
def path_for(options)
|
70
|
-
path = options[:script_name].to_s.chomp("/"
|
70
|
+
path = options[:script_name].to_s.chomp("/")
|
71
71
|
path << options[:path] if options.key?(:path)
|
72
72
|
|
73
73
|
add_trailing_slash(path) if options[:trailing_slash]
|
@@ -79,108 +79,108 @@ module ActionDispatch
|
|
79
79
|
|
80
80
|
private
|
81
81
|
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
end
|
88
|
-
|
89
|
-
def add_anchor(path, anchor)
|
90
|
-
if anchor
|
91
|
-
path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param)}"
|
82
|
+
def add_params(path, params)
|
83
|
+
params = { params: params } unless params.is_a?(Hash)
|
84
|
+
params.reject! { |_, v| v.to_param.nil? }
|
85
|
+
query = params.to_query
|
86
|
+
path << "?#{query}" unless query.empty?
|
92
87
|
end
|
93
|
-
end
|
94
88
|
|
95
|
-
|
96
|
-
|
97
|
-
|
89
|
+
def add_anchor(path, anchor)
|
90
|
+
if anchor
|
91
|
+
path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param)}"
|
92
|
+
end
|
93
|
+
end
|
98
94
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
end
|
95
|
+
def extract_domain_from(host, tld_length)
|
96
|
+
host.split(".").last(1 + tld_length).join(".")
|
97
|
+
end
|
103
98
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
elsif !path.include?(".")
|
108
|
-
path.sub!(/[^\/]\z|\A\z/, '\&/')
|
99
|
+
def extract_subdomains_from(host, tld_length)
|
100
|
+
parts = host.split(".")
|
101
|
+
parts[0..-(tld_length + 2)]
|
109
102
|
end
|
110
|
-
end
|
111
103
|
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
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
|
117
110
|
end
|
118
111
|
|
119
|
-
|
120
|
-
|
112
|
+
def build_host_url(host, port, protocol, options, path)
|
113
|
+
if match = host.match(HOST_REGEXP)
|
114
|
+
protocol ||= match[1] unless protocol == false
|
115
|
+
host = match[2]
|
116
|
+
port = match[3] unless options.key? :port
|
117
|
+
end
|
121
118
|
|
122
|
-
|
119
|
+
protocol = normalize_protocol protocol
|
120
|
+
host = normalize_host(host, options)
|
123
121
|
|
124
|
-
|
125
|
-
result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@"
|
126
|
-
end
|
122
|
+
result = protocol.dup
|
127
123
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
}
|
124
|
+
if options[:user] && options[:password]
|
125
|
+
result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@"
|
126
|
+
end
|
132
127
|
|
133
|
-
|
134
|
-
|
128
|
+
result << host
|
129
|
+
normalize_port(port, protocol) { |normalized_port|
|
130
|
+
result << ":#{normalized_port}"
|
131
|
+
}
|
135
132
|
|
136
|
-
|
137
|
-
|
138
|
-
end
|
133
|
+
result.concat path
|
134
|
+
end
|
139
135
|
|
140
|
-
|
141
|
-
|
142
|
-
when nil
|
143
|
-
"http://"
|
144
|
-
when false, "//"
|
145
|
-
"//"
|
146
|
-
when PROTOCOL_REGEXP
|
147
|
-
"#{$1}://"
|
148
|
-
else
|
149
|
-
raise ArgumentError, "Invalid :protocol option: #{protocol.inspect}"
|
136
|
+
def named_host?(host)
|
137
|
+
IP_HOST_REGEXP !~ host
|
150
138
|
end
|
151
|
-
end
|
152
139
|
|
153
|
-
|
154
|
-
|
140
|
+
def normalize_protocol(protocol)
|
141
|
+
case protocol
|
142
|
+
when nil
|
143
|
+
"http://"
|
144
|
+
when false, "//"
|
145
|
+
"//"
|
146
|
+
when PROTOCOL_REGEXP
|
147
|
+
"#{$1}://"
|
148
|
+
else
|
149
|
+
raise ArgumentError, "Invalid :protocol option: #{protocol.inspect}"
|
150
|
+
end
|
151
|
+
end
|
155
152
|
|
156
|
-
|
157
|
-
|
158
|
-
domain = options[:domain]
|
153
|
+
def normalize_host(_host, options)
|
154
|
+
return _host unless named_host?(_host)
|
159
155
|
|
160
|
-
|
161
|
-
|
162
|
-
|
156
|
+
tld_length = options[:tld_length] || @@tld_length
|
157
|
+
subdomain = options.fetch :subdomain, true
|
158
|
+
domain = options[:domain]
|
163
159
|
|
164
|
-
host
|
165
|
-
|
166
|
-
|
160
|
+
host = +""
|
161
|
+
if subdomain == true
|
162
|
+
return _host if domain.nil?
|
163
|
+
|
164
|
+
host << extract_subdomains_from(_host, tld_length).join(".")
|
165
|
+
elsif subdomain
|
166
|
+
host << subdomain.to_param
|
167
|
+
end
|
168
|
+
host << "." unless host.empty?
|
169
|
+
host << (domain || extract_domain_from(_host, tld_length))
|
170
|
+
host
|
167
171
|
end
|
168
|
-
host << "." unless host.empty?
|
169
|
-
host << (domain || extract_domain_from(_host, tld_length))
|
170
|
-
host
|
171
|
-
end
|
172
172
|
|
173
|
-
|
174
|
-
|
173
|
+
def normalize_port(port, protocol)
|
174
|
+
return unless port
|
175
175
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
176
|
+
case protocol
|
177
|
+
when "//" then yield port
|
178
|
+
when "https://"
|
179
|
+
yield port unless port.to_i == 443
|
180
|
+
else
|
181
|
+
yield port unless port.to_i == 80
|
182
|
+
end
|
182
183
|
end
|
183
|
-
end
|
184
184
|
end
|
185
185
|
|
186
186
|
def initialize
|
@@ -231,7 +231,7 @@ module ActionDispatch
|
|
231
231
|
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
232
232
|
# req.host # => "example.com"
|
233
233
|
def host
|
234
|
-
raw_host_with_port.sub(/:\d+$/, ""
|
234
|
+
raw_host_with_port.sub(/:\d+$/, "")
|
235
235
|
end
|
236
236
|
|
237
237
|
# Returns a \host:\port string for this request, such as "example.com" or
|