actionpack 6.0.0
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 +7 -0
- data/CHANGELOG.md +311 -0
- data/MIT-LICENSE +21 -0
- data/README.rdoc +58 -0
- data/lib/abstract_controller.rb +27 -0
- data/lib/abstract_controller/asset_paths.rb +12 -0
- data/lib/abstract_controller/base.rb +267 -0
- data/lib/abstract_controller/caching.rb +66 -0
- data/lib/abstract_controller/caching/fragments.rb +150 -0
- data/lib/abstract_controller/callbacks.rb +224 -0
- data/lib/abstract_controller/collector.rb +43 -0
- data/lib/abstract_controller/error.rb +6 -0
- data/lib/abstract_controller/helpers.rb +194 -0
- data/lib/abstract_controller/logger.rb +14 -0
- data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
- data/lib/abstract_controller/rendering.rb +127 -0
- data/lib/abstract_controller/translation.rb +32 -0
- data/lib/abstract_controller/url_for.rb +35 -0
- data/lib/action_controller.rb +67 -0
- data/lib/action_controller/api.rb +150 -0
- data/lib/action_controller/api/api_rendering.rb +16 -0
- data/lib/action_controller/base.rb +271 -0
- data/lib/action_controller/caching.rb +46 -0
- data/lib/action_controller/form_builder.rb +50 -0
- data/lib/action_controller/log_subscriber.rb +81 -0
- data/lib/action_controller/metal.rb +256 -0
- data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
- data/lib/action_controller/metal/conditional_get.rb +280 -0
- data/lib/action_controller/metal/content_security_policy.rb +52 -0
- data/lib/action_controller/metal/cookies.rb +16 -0
- data/lib/action_controller/metal/data_streaming.rb +151 -0
- data/lib/action_controller/metal/default_headers.rb +17 -0
- data/lib/action_controller/metal/etag_with_flash.rb +18 -0
- data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
- data/lib/action_controller/metal/exceptions.rb +74 -0
- data/lib/action_controller/metal/flash.rb +61 -0
- data/lib/action_controller/metal/force_ssl.rb +58 -0
- data/lib/action_controller/metal/head.rb +60 -0
- data/lib/action_controller/metal/helpers.rb +122 -0
- data/lib/action_controller/metal/http_authentication.rb +518 -0
- data/lib/action_controller/metal/implicit_render.rb +63 -0
- data/lib/action_controller/metal/instrumentation.rb +105 -0
- data/lib/action_controller/metal/live.rb +314 -0
- data/lib/action_controller/metal/mime_responds.rb +324 -0
- data/lib/action_controller/metal/parameter_encoding.rb +51 -0
- data/lib/action_controller/metal/params_wrapper.rb +297 -0
- data/lib/action_controller/metal/redirecting.rb +133 -0
- data/lib/action_controller/metal/renderers.rb +181 -0
- data/lib/action_controller/metal/rendering.rb +122 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +456 -0
- data/lib/action_controller/metal/rescue.rb +28 -0
- data/lib/action_controller/metal/streaming.rb +223 -0
- data/lib/action_controller/metal/strong_parameters.rb +1105 -0
- data/lib/action_controller/metal/testing.rb +16 -0
- data/lib/action_controller/metal/url_for.rb +58 -0
- data/lib/action_controller/railtie.rb +89 -0
- data/lib/action_controller/railties/helpers.rb +24 -0
- data/lib/action_controller/renderer.rb +130 -0
- data/lib/action_controller/template_assertions.rb +11 -0
- data/lib/action_controller/test_case.rb +626 -0
- data/lib/action_dispatch.rb +114 -0
- data/lib/action_dispatch/http/cache.rb +226 -0
- data/lib/action_dispatch/http/content_disposition.rb +45 -0
- data/lib/action_dispatch/http/content_security_policy.rb +284 -0
- data/lib/action_dispatch/http/filter_parameters.rb +86 -0
- data/lib/action_dispatch/http/filter_redirect.rb +37 -0
- data/lib/action_dispatch/http/headers.rb +132 -0
- data/lib/action_dispatch/http/mime_negotiation.rb +177 -0
- data/lib/action_dispatch/http/mime_type.rb +350 -0
- data/lib/action_dispatch/http/mime_types.rb +50 -0
- data/lib/action_dispatch/http/parameter_filter.rb +12 -0
- data/lib/action_dispatch/http/parameters.rb +136 -0
- data/lib/action_dispatch/http/rack_cache.rb +63 -0
- data/lib/action_dispatch/http/request.rb +427 -0
- data/lib/action_dispatch/http/response.rb +534 -0
- data/lib/action_dispatch/http/upload.rb +92 -0
- data/lib/action_dispatch/http/url.rb +350 -0
- data/lib/action_dispatch/journey.rb +7 -0
- data/lib/action_dispatch/journey/formatter.rb +189 -0
- data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
- data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
- data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
- data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
- data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
- data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
- data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
- data/lib/action_dispatch/journey/nodes/node.rb +141 -0
- data/lib/action_dispatch/journey/parser.rb +199 -0
- data/lib/action_dispatch/journey/parser.y +50 -0
- data/lib/action_dispatch/journey/parser_extras.rb +31 -0
- data/lib/action_dispatch/journey/path/pattern.rb +203 -0
- data/lib/action_dispatch/journey/route.rb +204 -0
- data/lib/action_dispatch/journey/router.rb +153 -0
- data/lib/action_dispatch/journey/router/utils.rb +102 -0
- data/lib/action_dispatch/journey/routes.rb +81 -0
- data/lib/action_dispatch/journey/scanner.rb +71 -0
- data/lib/action_dispatch/journey/visitors.rb +268 -0
- data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
- data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
- data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
- data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
- data/lib/action_dispatch/middleware/callbacks.rb +34 -0
- data/lib/action_dispatch/middleware/cookies.rb +663 -0
- data/lib/action_dispatch/middleware/debug_exceptions.rb +185 -0
- data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
- data/lib/action_dispatch/middleware/debug_view.rb +68 -0
- data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -0
- data/lib/action_dispatch/middleware/executor.rb +21 -0
- data/lib/action_dispatch/middleware/flash.rb +300 -0
- data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
- data/lib/action_dispatch/middleware/public_exceptions.rb +61 -0
- data/lib/action_dispatch/middleware/reloader.rb +12 -0
- data/lib/action_dispatch/middleware/remote_ip.rb +181 -0
- data/lib/action_dispatch/middleware/request_id.rb +43 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
- data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +113 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
- data/lib/action_dispatch/middleware/ssl.rb +150 -0
- data/lib/action_dispatch/middleware/stack.rb +148 -0
- data/lib/action_dispatch/middleware/static.rb +129 -0
- 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 +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
- 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 +38 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +165 -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 +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
- data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
- data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +203 -0
- data/lib/action_dispatch/railtie.rb +58 -0
- data/lib/action_dispatch/request/session.rb +242 -0
- data/lib/action_dispatch/request/utils.rb +78 -0
- data/lib/action_dispatch/routing.rb +261 -0
- data/lib/action_dispatch/routing/endpoint.rb +17 -0
- data/lib/action_dispatch/routing/inspector.rb +274 -0
- data/lib/action_dispatch/routing/mapper.rb +2289 -0
- data/lib/action_dispatch/routing/polymorphic_routes.rb +351 -0
- data/lib/action_dispatch/routing/redirection.rb +201 -0
- data/lib/action_dispatch/routing/route_set.rb +887 -0
- data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
- data/lib/action_dispatch/routing/url_for.rb +237 -0
- data/lib/action_dispatch/system_test_case.rb +168 -0
- data/lib/action_dispatch/system_testing/browser.rb +80 -0
- data/lib/action_dispatch/system_testing/driver.rb +68 -0
- data/lib/action_dispatch/system_testing/server.rb +31 -0
- data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +97 -0
- data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +33 -0
- data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
- data/lib/action_dispatch/testing/assertion_response.rb +47 -0
- data/lib/action_dispatch/testing/assertions.rb +24 -0
- data/lib/action_dispatch/testing/assertions/response.rb +106 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +234 -0
- data/lib/action_dispatch/testing/integration.rb +659 -0
- data/lib/action_dispatch/testing/request_encoder.rb +55 -0
- data/lib/action_dispatch/testing/test_process.rb +50 -0
- data/lib/action_dispatch/testing/test_request.rb +71 -0
- data/lib/action_dispatch/testing/test_response.rb +25 -0
- data/lib/action_pack.rb +26 -0
- data/lib/action_pack/gem_version.rb +17 -0
- data/lib/action_pack/version.rb +10 -0
- metadata +329 -0
@@ -0,0 +1,92 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module ActionDispatch
|
4
|
+
module Http
|
5
|
+
# Models uploaded files.
|
6
|
+
#
|
7
|
+
# The actual file is accessible via the +tempfile+ accessor, though some
|
8
|
+
# of its interface is available directly for convenience.
|
9
|
+
#
|
10
|
+
# Uploaded files are temporary files whose lifespan is one request. When
|
11
|
+
# the object is finalized Ruby unlinks the file, so there is no need to
|
12
|
+
# clean them with a separate maintenance task.
|
13
|
+
class UploadedFile
|
14
|
+
# The basename of the file in the client.
|
15
|
+
attr_accessor :original_filename
|
16
|
+
|
17
|
+
# A string with the MIME type of the file.
|
18
|
+
attr_accessor :content_type
|
19
|
+
|
20
|
+
# A +Tempfile+ object with the actual uploaded file. Note that some of
|
21
|
+
# its interface is available directly.
|
22
|
+
attr_accessor :tempfile
|
23
|
+
|
24
|
+
# A string with the headers of the multipart request.
|
25
|
+
attr_accessor :headers
|
26
|
+
|
27
|
+
def initialize(hash) # :nodoc:
|
28
|
+
@tempfile = hash[:tempfile]
|
29
|
+
raise(ArgumentError, ":tempfile is required") unless @tempfile
|
30
|
+
|
31
|
+
if hash[:filename]
|
32
|
+
@original_filename = hash[:filename].dup
|
33
|
+
|
34
|
+
begin
|
35
|
+
@original_filename.encode!(Encoding::UTF_8)
|
36
|
+
rescue EncodingError
|
37
|
+
@original_filename.force_encoding(Encoding::UTF_8)
|
38
|
+
end
|
39
|
+
else
|
40
|
+
@original_filename = nil
|
41
|
+
end
|
42
|
+
|
43
|
+
@content_type = hash[:type]
|
44
|
+
@headers = hash[:head]
|
45
|
+
end
|
46
|
+
|
47
|
+
# Shortcut for +tempfile.read+.
|
48
|
+
def read(length = nil, buffer = nil)
|
49
|
+
@tempfile.read(length, buffer)
|
50
|
+
end
|
51
|
+
|
52
|
+
# Shortcut for +tempfile.open+.
|
53
|
+
def open
|
54
|
+
@tempfile.open
|
55
|
+
end
|
56
|
+
|
57
|
+
# Shortcut for +tempfile.close+.
|
58
|
+
def close(unlink_now = false)
|
59
|
+
@tempfile.close(unlink_now)
|
60
|
+
end
|
61
|
+
|
62
|
+
# Shortcut for +tempfile.path+.
|
63
|
+
def path
|
64
|
+
@tempfile.path
|
65
|
+
end
|
66
|
+
|
67
|
+
# Shortcut for +tempfile.to_path+.
|
68
|
+
def to_path
|
69
|
+
@tempfile.to_path
|
70
|
+
end
|
71
|
+
|
72
|
+
# Shortcut for +tempfile.rewind+.
|
73
|
+
def rewind
|
74
|
+
@tempfile.rewind
|
75
|
+
end
|
76
|
+
|
77
|
+
# Shortcut for +tempfile.size+.
|
78
|
+
def size
|
79
|
+
@tempfile.size
|
80
|
+
end
|
81
|
+
|
82
|
+
# Shortcut for +tempfile.eof?+.
|
83
|
+
def eof?
|
84
|
+
@tempfile.eof?
|
85
|
+
end
|
86
|
+
|
87
|
+
def to_io
|
88
|
+
@tempfile.to_io
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
@@ -0,0 +1,350 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/core_ext/module/attribute_accessors"
|
4
|
+
|
5
|
+
module ActionDispatch
|
6
|
+
module Http
|
7
|
+
module URL
|
8
|
+
IP_HOST_REGEXP = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/
|
9
|
+
HOST_REGEXP = /(^[^:]+:\/\/)?(\[[^\]]+\]|[^:]+)(?::(\d+$))?/
|
10
|
+
PROTOCOL_REGEXP = /^([^:]+)(:)?(\/\/)?$/
|
11
|
+
|
12
|
+
mattr_accessor :tld_length, default: 1
|
13
|
+
|
14
|
+
class << self
|
15
|
+
# Returns the domain part of a host given the domain level.
|
16
|
+
#
|
17
|
+
# # Top-level domain example
|
18
|
+
# extract_domain('www.example.com', 1) # => "example.com"
|
19
|
+
# # Second-level domain example
|
20
|
+
# extract_domain('dev.www.example.co.uk', 2) # => "example.co.uk"
|
21
|
+
def extract_domain(host, tld_length)
|
22
|
+
extract_domain_from(host, tld_length) if named_host?(host)
|
23
|
+
end
|
24
|
+
|
25
|
+
# Returns the subdomains of a host as an Array given the domain level.
|
26
|
+
#
|
27
|
+
# # Top-level domain example
|
28
|
+
# extract_subdomains('www.example.com', 1) # => ["www"]
|
29
|
+
# # Second-level domain example
|
30
|
+
# extract_subdomains('dev.www.example.co.uk', 2) # => ["dev", "www"]
|
31
|
+
def extract_subdomains(host, tld_length)
|
32
|
+
if named_host?(host)
|
33
|
+
extract_subdomains_from(host, tld_length)
|
34
|
+
else
|
35
|
+
[]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Returns the subdomains of a host as a String given the domain level.
|
40
|
+
#
|
41
|
+
# # Top-level domain example
|
42
|
+
# extract_subdomain('www.example.com', 1) # => "www"
|
43
|
+
# # Second-level domain example
|
44
|
+
# extract_subdomain('dev.www.example.co.uk', 2) # => "dev.www"
|
45
|
+
def extract_subdomain(host, tld_length)
|
46
|
+
extract_subdomains(host, tld_length).join(".")
|
47
|
+
end
|
48
|
+
|
49
|
+
def url_for(options)
|
50
|
+
if options[:only_path]
|
51
|
+
path_for options
|
52
|
+
else
|
53
|
+
full_url_for options
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def full_url_for(options)
|
58
|
+
host = options[:host]
|
59
|
+
protocol = options[:protocol]
|
60
|
+
port = options[:port]
|
61
|
+
|
62
|
+
unless host
|
63
|
+
raise ArgumentError, "Missing host to link to! Please provide the :host parameter, set default_url_options[:host], or set :only_path to true"
|
64
|
+
end
|
65
|
+
|
66
|
+
build_host_url(host, port, protocol, options, path_for(options))
|
67
|
+
end
|
68
|
+
|
69
|
+
def path_for(options)
|
70
|
+
path = options[:script_name].to_s.chomp("/")
|
71
|
+
path << options[:path] if options.key?(:path)
|
72
|
+
|
73
|
+
add_trailing_slash(path) if options[:trailing_slash]
|
74
|
+
add_params(path, options[:params]) if options.key?(:params)
|
75
|
+
add_anchor(path, options[:anchor]) if options.key?(:anchor)
|
76
|
+
|
77
|
+
path
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
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?
|
87
|
+
end
|
88
|
+
|
89
|
+
def add_anchor(path, anchor)
|
90
|
+
if anchor
|
91
|
+
path << "##{Journey::Router::Utils.escape_fragment(anchor.to_param)}"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def extract_domain_from(host, tld_length)
|
96
|
+
host.split(".").last(1 + tld_length).join(".")
|
97
|
+
end
|
98
|
+
|
99
|
+
def extract_subdomains_from(host, tld_length)
|
100
|
+
parts = host.split(".")
|
101
|
+
parts[0..-(tld_length + 2)]
|
102
|
+
end
|
103
|
+
|
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
|
+
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
|
118
|
+
|
119
|
+
protocol = normalize_protocol protocol
|
120
|
+
host = normalize_host(host, options)
|
121
|
+
|
122
|
+
result = protocol.dup
|
123
|
+
|
124
|
+
if options[:user] && options[:password]
|
125
|
+
result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@"
|
126
|
+
end
|
127
|
+
|
128
|
+
result << host
|
129
|
+
normalize_port(port, protocol) { |normalized_port|
|
130
|
+
result << ":#{normalized_port}"
|
131
|
+
}
|
132
|
+
|
133
|
+
result.concat path
|
134
|
+
end
|
135
|
+
|
136
|
+
def named_host?(host)
|
137
|
+
IP_HOST_REGEXP !~ host
|
138
|
+
end
|
139
|
+
|
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
|
152
|
+
|
153
|
+
def normalize_host(_host, options)
|
154
|
+
return _host unless named_host?(_host)
|
155
|
+
|
156
|
+
tld_length = options[:tld_length] || @@tld_length
|
157
|
+
subdomain = options.fetch :subdomain, true
|
158
|
+
domain = options[:domain]
|
159
|
+
|
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
|
171
|
+
end
|
172
|
+
|
173
|
+
def normalize_port(port, protocol)
|
174
|
+
return unless port
|
175
|
+
|
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
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def initialize
|
187
|
+
super
|
188
|
+
@protocol = nil
|
189
|
+
@port = nil
|
190
|
+
end
|
191
|
+
|
192
|
+
# Returns the complete URL used for this request.
|
193
|
+
#
|
194
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
195
|
+
# req.url # => "http://example.com"
|
196
|
+
def url
|
197
|
+
protocol + host_with_port + fullpath
|
198
|
+
end
|
199
|
+
|
200
|
+
# Returns 'https://' if this is an SSL request and 'http://' otherwise.
|
201
|
+
#
|
202
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
203
|
+
# req.protocol # => "http://"
|
204
|
+
#
|
205
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com', 'HTTPS' => 'on'
|
206
|
+
# req.protocol # => "https://"
|
207
|
+
def protocol
|
208
|
+
@protocol ||= ssl? ? "https://" : "http://"
|
209
|
+
end
|
210
|
+
|
211
|
+
# Returns the \host and port for this request, such as "example.com:8080".
|
212
|
+
#
|
213
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
214
|
+
# req.raw_host_with_port # => "example.com"
|
215
|
+
#
|
216
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
217
|
+
# req.raw_host_with_port # => "example.com:80"
|
218
|
+
#
|
219
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
220
|
+
# req.raw_host_with_port # => "example.com:8080"
|
221
|
+
def raw_host_with_port
|
222
|
+
if forwarded = x_forwarded_host.presence
|
223
|
+
forwarded.split(/,\s?/).last
|
224
|
+
else
|
225
|
+
get_header("HTTP_HOST") || "#{server_name || server_addr}:#{get_header('SERVER_PORT')}"
|
226
|
+
end
|
227
|
+
end
|
228
|
+
|
229
|
+
# Returns the host for this request, such as "example.com".
|
230
|
+
#
|
231
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
232
|
+
# req.host # => "example.com"
|
233
|
+
def host
|
234
|
+
raw_host_with_port.sub(/:\d+$/, "")
|
235
|
+
end
|
236
|
+
|
237
|
+
# Returns a \host:\port string for this request, such as "example.com" or
|
238
|
+
# "example.com:8080". Port is only included if it is not a default port
|
239
|
+
# (80 or 443)
|
240
|
+
#
|
241
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
242
|
+
# req.host_with_port # => "example.com"
|
243
|
+
#
|
244
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
245
|
+
# req.host_with_port # => "example.com"
|
246
|
+
#
|
247
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
248
|
+
# req.host_with_port # => "example.com:8080"
|
249
|
+
def host_with_port
|
250
|
+
"#{host}#{port_string}"
|
251
|
+
end
|
252
|
+
|
253
|
+
# Returns the port number of this request as an integer.
|
254
|
+
#
|
255
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com'
|
256
|
+
# req.port # => 80
|
257
|
+
#
|
258
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
259
|
+
# req.port # => 8080
|
260
|
+
def port
|
261
|
+
@port ||= begin
|
262
|
+
if raw_host_with_port =~ /:(\d+)$/
|
263
|
+
$1.to_i
|
264
|
+
else
|
265
|
+
standard_port
|
266
|
+
end
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
# Returns the standard \port number for this request's protocol.
|
271
|
+
#
|
272
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
273
|
+
# req.standard_port # => 80
|
274
|
+
def standard_port
|
275
|
+
case protocol
|
276
|
+
when "https://" then 443
|
277
|
+
else 80
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
# Returns whether this request is using the standard port
|
282
|
+
#
|
283
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
284
|
+
# req.standard_port? # => true
|
285
|
+
#
|
286
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
287
|
+
# req.standard_port? # => false
|
288
|
+
def standard_port?
|
289
|
+
port == standard_port
|
290
|
+
end
|
291
|
+
|
292
|
+
# Returns a number \port suffix like 8080 if the \port number of this request
|
293
|
+
# is not the default HTTP \port 80 or HTTPS \port 443.
|
294
|
+
#
|
295
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
296
|
+
# req.optional_port # => nil
|
297
|
+
#
|
298
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
299
|
+
# req.optional_port # => 8080
|
300
|
+
def optional_port
|
301
|
+
standard_port? ? nil : port
|
302
|
+
end
|
303
|
+
|
304
|
+
# Returns a string \port suffix, including colon, like ":8080" if the \port
|
305
|
+
# number of this request is not the default HTTP \port 80 or HTTPS \port 443.
|
306
|
+
#
|
307
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:80'
|
308
|
+
# req.port_string # => ""
|
309
|
+
#
|
310
|
+
# req = ActionDispatch::Request.new 'HTTP_HOST' => 'example.com:8080'
|
311
|
+
# req.port_string # => ":8080"
|
312
|
+
def port_string
|
313
|
+
standard_port? ? "" : ":#{port}"
|
314
|
+
end
|
315
|
+
|
316
|
+
# Returns the requested port, such as 8080, based on SERVER_PORT
|
317
|
+
#
|
318
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '80'
|
319
|
+
# req.server_port # => 80
|
320
|
+
#
|
321
|
+
# req = ActionDispatch::Request.new 'SERVER_PORT' => '8080'
|
322
|
+
# req.server_port # => 8080
|
323
|
+
def server_port
|
324
|
+
get_header("SERVER_PORT").to_i
|
325
|
+
end
|
326
|
+
|
327
|
+
# Returns the \domain part of a \host, such as "rubyonrails.org" in "www.rubyonrails.org". You can specify
|
328
|
+
# a different <tt>tld_length</tt>, such as 2 to catch rubyonrails.co.uk in "www.rubyonrails.co.uk".
|
329
|
+
def domain(tld_length = @@tld_length)
|
330
|
+
ActionDispatch::Http::URL.extract_domain(host, tld_length)
|
331
|
+
end
|
332
|
+
|
333
|
+
# Returns all the \subdomains as an array, so <tt>["dev", "www"]</tt> would be
|
334
|
+
# returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
|
335
|
+
# such as 2 to catch <tt>["www"]</tt> instead of <tt>["www", "rubyonrails"]</tt>
|
336
|
+
# in "www.rubyonrails.co.uk".
|
337
|
+
def subdomains(tld_length = @@tld_length)
|
338
|
+
ActionDispatch::Http::URL.extract_subdomains(host, tld_length)
|
339
|
+
end
|
340
|
+
|
341
|
+
# Returns all the \subdomains as a string, so <tt>"dev.www"</tt> would be
|
342
|
+
# returned for "dev.www.rubyonrails.org". You can specify a different <tt>tld_length</tt>,
|
343
|
+
# such as 2 to catch <tt>"www"</tt> instead of <tt>"www.rubyonrails"</tt>
|
344
|
+
# in "www.rubyonrails.co.uk".
|
345
|
+
def subdomain(tld_length = @@tld_length)
|
346
|
+
ActionDispatch::Http::URL.extract_subdomain(host, tld_length)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
end
|
350
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "action_dispatch/journey/router"
|
4
|
+
require "action_dispatch/journey/gtg/builder"
|
5
|
+
require "action_dispatch/journey/gtg/simulator"
|
6
|
+
require "action_dispatch/journey/nfa/builder"
|
7
|
+
require "action_dispatch/journey/nfa/simulator"
|