diff options
Diffstat (limited to 'actionpack/lib/action_dispatch')
-rw-r--r-- | actionpack/lib/action_dispatch/http/cache.rb | 2 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/http/url.rb | 101 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/journey/router.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/route_set.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/testing/integration.rb | 2 |
5 files changed, 61 insertions, 49 deletions
diff --git a/actionpack/lib/action_dispatch/http/cache.rb b/actionpack/lib/action_dispatch/http/cache.rb index f9b278349e..63a3cbc90b 100644 --- a/actionpack/lib/action_dispatch/http/cache.rb +++ b/actionpack/lib/action_dispatch/http/cache.rb @@ -92,7 +92,7 @@ module ActionDispatch LAST_MODIFIED = "Last-Modified".freeze ETAG = "ETag".freeze CACHE_CONTROL = "Cache-Control".freeze - SPECIAL_KEYS = %w[extras no-cache max-age public must-revalidate] + SPECIAL_KEYS = Set.new(%w[extras no-cache max-age public must-revalidate]) def cache_control_segments if cache_control = self[CACHE_CONTROL] diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 4cba4f5f37..3997c6ee98 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -5,27 +5,26 @@ module ActionDispatch module Http module URL IP_HOST_REGEXP = /\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/ - HOST_REGEXP = /(^.*:\/\/)?([^:]+)(?::(\d+$))?/ + HOST_REGEXP = /(^[^:]+:\/\/)?([^:]+)(?::(\d+$))?/ PROTOCOL_REGEXP = /^([^:]+)(:)?(\/\/)?$/ mattr_accessor :tld_length self.tld_length = 1 class << self - def extract_domain(host, tld_length = @@tld_length) - host.split('.').last(1 + tld_length).join('.') if named_host?(host) + def extract_domain(host, tld_length) + extract_domain_from(host, tld_length) if named_host?(host) end - def extract_subdomains(host, tld_length = @@tld_length) + def extract_subdomains(host, tld_length) if named_host?(host) - parts = host.split('.') - parts[0..-(tld_length + 2)] + extract_subdomains_from(host, tld_length) else [] end end - def extract_subdomain(host, tld_length = @@tld_length) + def extract_subdomain(host, tld_length) extract_subdomains(host, tld_length).join('.') end @@ -37,13 +36,13 @@ module ActionDispatch path = options[:script_name].to_s.chomp("/") path << options[:path].to_s - add_trailing_slash(path) if options[:trailing_slash] + path = add_trailing_slash(path) if options[:trailing_slash] - result = path - - unless options[:only_path] - result.prepend build_host_url(options) - end + result = if options[:only_path] + path + else + build_host_url(options).concat path + end if options.key? :params params = options[:params].is_a?(Hash) ? @@ -60,6 +59,15 @@ module ActionDispatch private + def extract_domain_from(host, tld_length) + host.split('.').last(1 + tld_length).join('.') + end + + def extract_subdomains_from(host, tld_length) + parts = host.split('.') + parts[0..-(tld_length + 2)] + end + def add_trailing_slash(path) # includes querysting if path.include?('?') @@ -73,38 +81,38 @@ module ActionDispatch end def build_host_url(options) - if match = options[:host].match(HOST_REGEXP) - options[:protocol] ||= match[1] unless options[:protocol] == false - options[:host] = match[2] - options[:port] = match[3] unless options.key?(:port) + protocol = options[:protocol] + host = options[:host] + port = options[:port] + if match = host.match(HOST_REGEXP) + protocol ||= match[1] unless protocol == false + host = match[2] + port = match[3] unless options.key? :port end - options[:protocol] = normalize_protocol(options) - options[:host] = normalize_host(options) - options[:port] = normalize_port(options) + protocol = normalize_protocol protocol + host = normalize_host(host, options) - result = options[:protocol] + result = protocol.dup if options[:user] && options[:password] result << "#{Rack::Utils.escape(options[:user])}:#{Rack::Utils.escape(options[:password])}@" end - result << options[:host] - result << ":#{options[:port]}" if options[:port] + result << host + normalize_port(port, protocol) { |normalized_port| + result << ":#{normalized_port}" + } result end def named_host?(host) - host && IP_HOST_REGEXP !~ host - end - - def same_host?(options) - (options[:subdomain] == true || !options.key?(:subdomain)) && options[:domain].nil? + IP_HOST_REGEXP !~ host end - def normalize_protocol(options) - case options[:protocol] + def normalize_protocol(protocol) + case protocol when nil "http://" when false, "//" @@ -112,36 +120,39 @@ module ActionDispatch when PROTOCOL_REGEXP "#{$1}://" else - raise ArgumentError, "Invalid :protocol option: #{options[:protocol].inspect}" + raise ArgumentError, "Invalid :protocol option: #{protocol.inspect}" end end - def normalize_host(options) - return options[:host] if !named_host?(options[:host]) || same_host?(options) + def normalize_host(_host, options) + return _host unless named_host?(_host) tld_length = options[:tld_length] || @@tld_length + subdomain = options.fetch :subdomain, true + domain = options[:domain] host = "" - if options[:subdomain] == true || !options.key?(:subdomain) - host << extract_subdomain(options[:host], tld_length).to_param - elsif options[:subdomain].present? - host << options[:subdomain].to_param + if subdomain == true + return _host if domain.nil? + + host << extract_subdomains_from(_host, tld_length).join('.') + elsif subdomain + host << subdomain.to_param end host << "." unless host.empty? - host << (options[:domain] || extract_domain(options[:host], tld_length)) + host << (domain || extract_domain_from(_host, tld_length)) host end - def normalize_port(options) - return nil if options[:port].nil? || options[:port] == false + def normalize_port(port, protocol) + return unless port - case options[:protocol] - when "//" - options[:port] + case protocol + when "//" then yield port when "https://" - options[:port].to_i == 443 ? nil : options[:port] + yield port unless port.to_i == 443 else - options[:port].to_i == 80 ? nil : options[:port] + yield port unless port.to_i == 80 end end end diff --git a/actionpack/lib/action_dispatch/journey/router.rb b/actionpack/lib/action_dispatch/journey/router.rb index 74fa9ee3a2..fe3fc0a9fa 100644 --- a/actionpack/lib/action_dispatch/journey/router.rb +++ b/actionpack/lib/action_dispatch/journey/router.rb @@ -35,6 +35,7 @@ module ActionDispatch unless route.path.anchored req.script_name = (script_name.to_s + match.to_s).chomp('/') req.path_info = match.post_match + req.path_info = "/" + req.path_info unless req.path_info.start_with? "/" end req.path_parameters = set_params.merge parameters diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index bdda802195..69535faabd 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -420,7 +420,7 @@ module ActionDispatch path = conditions.delete :path_info ast = conditions.delete :parsed_path_info - path = build_path(path, ast, requirements, SEPARATORS, anchor) + path = build_path(path, ast, requirements, anchor) conditions = build_conditions(conditions, path.names.map { |x| x.to_sym }) route = @set.add_route(app, path, conditions, defaults, name) @@ -428,7 +428,7 @@ module ActionDispatch route end - def build_path(path, ast, requirements, separators, anchor) + def build_path(path, ast, requirements, anchor) strexp = Journey::Router::Strexp.new( ast, path, diff --git a/actionpack/lib/action_dispatch/testing/integration.rb b/actionpack/lib/action_dispatch/testing/integration.rb index af3bc26691..17765d851b 100644 --- a/actionpack/lib/action_dispatch/testing/integration.rb +++ b/actionpack/lib/action_dispatch/testing/integration.rb @@ -347,7 +347,7 @@ module ActionDispatch # By default, a single session is automatically created for you, but you # can use this method to open multiple sessions that ought to be tested # simultaneously. - def open_session(app = nil) + def open_session dup.tap do |session| yield session if block_given? end |