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.

Files changed (181) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +311 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +58 -0
  5. data/lib/abstract_controller.rb +27 -0
  6. data/lib/abstract_controller/asset_paths.rb +12 -0
  7. data/lib/abstract_controller/base.rb +267 -0
  8. data/lib/abstract_controller/caching.rb +66 -0
  9. data/lib/abstract_controller/caching/fragments.rb +150 -0
  10. data/lib/abstract_controller/callbacks.rb +224 -0
  11. data/lib/abstract_controller/collector.rb +43 -0
  12. data/lib/abstract_controller/error.rb +6 -0
  13. data/lib/abstract_controller/helpers.rb +194 -0
  14. data/lib/abstract_controller/logger.rb +14 -0
  15. data/lib/abstract_controller/railties/routes_helpers.rb +20 -0
  16. data/lib/abstract_controller/rendering.rb +127 -0
  17. data/lib/abstract_controller/translation.rb +32 -0
  18. data/lib/abstract_controller/url_for.rb +35 -0
  19. data/lib/action_controller.rb +67 -0
  20. data/lib/action_controller/api.rb +150 -0
  21. data/lib/action_controller/api/api_rendering.rb +16 -0
  22. data/lib/action_controller/base.rb +271 -0
  23. data/lib/action_controller/caching.rb +46 -0
  24. data/lib/action_controller/form_builder.rb +50 -0
  25. data/lib/action_controller/log_subscriber.rb +81 -0
  26. data/lib/action_controller/metal.rb +256 -0
  27. data/lib/action_controller/metal/basic_implicit_render.rb +13 -0
  28. data/lib/action_controller/metal/conditional_get.rb +280 -0
  29. data/lib/action_controller/metal/content_security_policy.rb +52 -0
  30. data/lib/action_controller/metal/cookies.rb +16 -0
  31. data/lib/action_controller/metal/data_streaming.rb +151 -0
  32. data/lib/action_controller/metal/default_headers.rb +17 -0
  33. data/lib/action_controller/metal/etag_with_flash.rb +18 -0
  34. data/lib/action_controller/metal/etag_with_template_digest.rb +57 -0
  35. data/lib/action_controller/metal/exceptions.rb +74 -0
  36. data/lib/action_controller/metal/flash.rb +61 -0
  37. data/lib/action_controller/metal/force_ssl.rb +58 -0
  38. data/lib/action_controller/metal/head.rb +60 -0
  39. data/lib/action_controller/metal/helpers.rb +122 -0
  40. data/lib/action_controller/metal/http_authentication.rb +518 -0
  41. data/lib/action_controller/metal/implicit_render.rb +63 -0
  42. data/lib/action_controller/metal/instrumentation.rb +105 -0
  43. data/lib/action_controller/metal/live.rb +314 -0
  44. data/lib/action_controller/metal/mime_responds.rb +324 -0
  45. data/lib/action_controller/metal/parameter_encoding.rb +51 -0
  46. data/lib/action_controller/metal/params_wrapper.rb +297 -0
  47. data/lib/action_controller/metal/redirecting.rb +133 -0
  48. data/lib/action_controller/metal/renderers.rb +181 -0
  49. data/lib/action_controller/metal/rendering.rb +122 -0
  50. data/lib/action_controller/metal/request_forgery_protection.rb +456 -0
  51. data/lib/action_controller/metal/rescue.rb +28 -0
  52. data/lib/action_controller/metal/streaming.rb +223 -0
  53. data/lib/action_controller/metal/strong_parameters.rb +1105 -0
  54. data/lib/action_controller/metal/testing.rb +16 -0
  55. data/lib/action_controller/metal/url_for.rb +58 -0
  56. data/lib/action_controller/railtie.rb +89 -0
  57. data/lib/action_controller/railties/helpers.rb +24 -0
  58. data/lib/action_controller/renderer.rb +130 -0
  59. data/lib/action_controller/template_assertions.rb +11 -0
  60. data/lib/action_controller/test_case.rb +626 -0
  61. data/lib/action_dispatch.rb +114 -0
  62. data/lib/action_dispatch/http/cache.rb +226 -0
  63. data/lib/action_dispatch/http/content_disposition.rb +45 -0
  64. data/lib/action_dispatch/http/content_security_policy.rb +284 -0
  65. data/lib/action_dispatch/http/filter_parameters.rb +86 -0
  66. data/lib/action_dispatch/http/filter_redirect.rb +37 -0
  67. data/lib/action_dispatch/http/headers.rb +132 -0
  68. data/lib/action_dispatch/http/mime_negotiation.rb +177 -0
  69. data/lib/action_dispatch/http/mime_type.rb +350 -0
  70. data/lib/action_dispatch/http/mime_types.rb +50 -0
  71. data/lib/action_dispatch/http/parameter_filter.rb +12 -0
  72. data/lib/action_dispatch/http/parameters.rb +136 -0
  73. data/lib/action_dispatch/http/rack_cache.rb +63 -0
  74. data/lib/action_dispatch/http/request.rb +427 -0
  75. data/lib/action_dispatch/http/response.rb +534 -0
  76. data/lib/action_dispatch/http/upload.rb +92 -0
  77. data/lib/action_dispatch/http/url.rb +350 -0
  78. data/lib/action_dispatch/journey.rb +7 -0
  79. data/lib/action_dispatch/journey/formatter.rb +189 -0
  80. data/lib/action_dispatch/journey/gtg/builder.rb +164 -0
  81. data/lib/action_dispatch/journey/gtg/simulator.rb +41 -0
  82. data/lib/action_dispatch/journey/gtg/transition_table.rb +158 -0
  83. data/lib/action_dispatch/journey/nfa/builder.rb +78 -0
  84. data/lib/action_dispatch/journey/nfa/dot.rb +36 -0
  85. data/lib/action_dispatch/journey/nfa/simulator.rb +47 -0
  86. data/lib/action_dispatch/journey/nfa/transition_table.rb +120 -0
  87. data/lib/action_dispatch/journey/nodes/node.rb +141 -0
  88. data/lib/action_dispatch/journey/parser.rb +199 -0
  89. data/lib/action_dispatch/journey/parser.y +50 -0
  90. data/lib/action_dispatch/journey/parser_extras.rb +31 -0
  91. data/lib/action_dispatch/journey/path/pattern.rb +203 -0
  92. data/lib/action_dispatch/journey/route.rb +204 -0
  93. data/lib/action_dispatch/journey/router.rb +153 -0
  94. data/lib/action_dispatch/journey/router/utils.rb +102 -0
  95. data/lib/action_dispatch/journey/routes.rb +81 -0
  96. data/lib/action_dispatch/journey/scanner.rb +71 -0
  97. data/lib/action_dispatch/journey/visitors.rb +268 -0
  98. data/lib/action_dispatch/journey/visualizer/fsm.css +30 -0
  99. data/lib/action_dispatch/journey/visualizer/fsm.js +134 -0
  100. data/lib/action_dispatch/journey/visualizer/index.html.erb +52 -0
  101. data/lib/action_dispatch/middleware/actionable_exceptions.rb +39 -0
  102. data/lib/action_dispatch/middleware/callbacks.rb +34 -0
  103. data/lib/action_dispatch/middleware/cookies.rb +663 -0
  104. data/lib/action_dispatch/middleware/debug_exceptions.rb +185 -0
  105. data/lib/action_dispatch/middleware/debug_locks.rb +124 -0
  106. data/lib/action_dispatch/middleware/debug_view.rb +68 -0
  107. data/lib/action_dispatch/middleware/exception_wrapper.rb +181 -0
  108. data/lib/action_dispatch/middleware/executor.rb +21 -0
  109. data/lib/action_dispatch/middleware/flash.rb +300 -0
  110. data/lib/action_dispatch/middleware/host_authorization.rb +103 -0
  111. data/lib/action_dispatch/middleware/public_exceptions.rb +61 -0
  112. data/lib/action_dispatch/middleware/reloader.rb +12 -0
  113. data/lib/action_dispatch/middleware/remote_ip.rb +181 -0
  114. data/lib/action_dispatch/middleware/request_id.rb +43 -0
  115. data/lib/action_dispatch/middleware/session/abstract_store.rb +92 -0
  116. data/lib/action_dispatch/middleware/session/cache_store.rb +54 -0
  117. data/lib/action_dispatch/middleware/session/cookie_store.rb +113 -0
  118. data/lib/action_dispatch/middleware/session/mem_cache_store.rb +28 -0
  119. data/lib/action_dispatch/middleware/show_exceptions.rb +62 -0
  120. data/lib/action_dispatch/middleware/ssl.rb +150 -0
  121. data/lib/action_dispatch/middleware/stack.rb +148 -0
  122. data/lib/action_dispatch/middleware/static.rb +129 -0
  123. data/lib/action_dispatch/middleware/templates/rescues/_actions.html.erb +13 -0
  124. data/lib/action_dispatch/middleware/templates/rescues/_actions.text.erb +0 -0
  125. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.html.erb +24 -0
  126. data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.text.erb +23 -0
  127. data/lib/action_dispatch/middleware/templates/rescues/_source.html.erb +29 -0
  128. data/lib/action_dispatch/middleware/templates/rescues/_source.text.erb +8 -0
  129. data/lib/action_dispatch/middleware/templates/rescues/_trace.html.erb +62 -0
  130. data/lib/action_dispatch/middleware/templates/rescues/_trace.text.erb +9 -0
  131. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.html.erb +7 -0
  132. data/lib/action_dispatch/middleware/templates/rescues/blocked_host.text.erb +5 -0
  133. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb +38 -0
  134. data/lib/action_dispatch/middleware/templates/rescues/diagnostics.text.erb +9 -0
  135. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.html.erb +24 -0
  136. data/lib/action_dispatch/middleware/templates/rescues/invalid_statement.text.erb +15 -0
  137. data/lib/action_dispatch/middleware/templates/rescues/layout.erb +165 -0
  138. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.html.erb +19 -0
  139. data/lib/action_dispatch/middleware/templates/rescues/missing_exact_template.text.erb +3 -0
  140. data/lib/action_dispatch/middleware/templates/rescues/missing_template.html.erb +11 -0
  141. data/lib/action_dispatch/middleware/templates/rescues/missing_template.text.erb +3 -0
  142. data/lib/action_dispatch/middleware/templates/rescues/routing_error.html.erb +32 -0
  143. data/lib/action_dispatch/middleware/templates/rescues/routing_error.text.erb +11 -0
  144. data/lib/action_dispatch/middleware/templates/rescues/template_error.html.erb +20 -0
  145. data/lib/action_dispatch/middleware/templates/rescues/template_error.text.erb +7 -0
  146. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.html.erb +6 -0
  147. data/lib/action_dispatch/middleware/templates/rescues/unknown_action.text.erb +3 -0
  148. data/lib/action_dispatch/middleware/templates/routes/_route.html.erb +16 -0
  149. data/lib/action_dispatch/middleware/templates/routes/_table.html.erb +203 -0
  150. data/lib/action_dispatch/railtie.rb +58 -0
  151. data/lib/action_dispatch/request/session.rb +242 -0
  152. data/lib/action_dispatch/request/utils.rb +78 -0
  153. data/lib/action_dispatch/routing.rb +261 -0
  154. data/lib/action_dispatch/routing/endpoint.rb +17 -0
  155. data/lib/action_dispatch/routing/inspector.rb +274 -0
  156. data/lib/action_dispatch/routing/mapper.rb +2289 -0
  157. data/lib/action_dispatch/routing/polymorphic_routes.rb +351 -0
  158. data/lib/action_dispatch/routing/redirection.rb +201 -0
  159. data/lib/action_dispatch/routing/route_set.rb +887 -0
  160. data/lib/action_dispatch/routing/routes_proxy.rb +69 -0
  161. data/lib/action_dispatch/routing/url_for.rb +237 -0
  162. data/lib/action_dispatch/system_test_case.rb +168 -0
  163. data/lib/action_dispatch/system_testing/browser.rb +80 -0
  164. data/lib/action_dispatch/system_testing/driver.rb +68 -0
  165. data/lib/action_dispatch/system_testing/server.rb +31 -0
  166. data/lib/action_dispatch/system_testing/test_helpers/screenshot_helper.rb +97 -0
  167. data/lib/action_dispatch/system_testing/test_helpers/setup_and_teardown.rb +33 -0
  168. data/lib/action_dispatch/system_testing/test_helpers/undef_methods.rb +26 -0
  169. data/lib/action_dispatch/testing/assertion_response.rb +47 -0
  170. data/lib/action_dispatch/testing/assertions.rb +24 -0
  171. data/lib/action_dispatch/testing/assertions/response.rb +106 -0
  172. data/lib/action_dispatch/testing/assertions/routing.rb +234 -0
  173. data/lib/action_dispatch/testing/integration.rb +659 -0
  174. data/lib/action_dispatch/testing/request_encoder.rb +55 -0
  175. data/lib/action_dispatch/testing/test_process.rb +50 -0
  176. data/lib/action_dispatch/testing/test_request.rb +71 -0
  177. data/lib/action_dispatch/testing/test_response.rb +25 -0
  178. data/lib/action_pack.rb +26 -0
  179. data/lib/action_pack/gem_version.rb +17 -0
  180. data/lib/action_pack/version.rb +10 -0
  181. 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"