Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Cleanup the style and minor perf of URLMap

URLMap was a little harder to follow than it need be, so I used my handy
Code Dremel(tm) on it.

I've removed the uses of Hash#merge! since they unnessarily created
extra Hash objects just to update the env.
  • Loading branch information...
commit 6ccb9130b0229e11dfb145c2456323cb3f9fdad3 1 parent 5e43924
@evanphx evanphx authored
Showing with 28 additions and 13 deletions.
  1. +28 −13 lib/rack/urlmap.rb
View
41 lib/rack/urlmap.rb
@@ -19,9 +19,6 @@ def initialize(map = {})
end
def remap(map)
- longest_path_first = lambda do |(host, location, _, _)|
- [host ? -host.size : NEGATIVE_INFINITY, -location.size]
- end
@mapping = map.map { |location, app|
if location =~ %r{\Ahttps?://(.*?)(/.*)}
host, location = $1, $2
@@ -32,28 +29,46 @@ def remap(map)
unless location[0] == ?/
raise ArgumentError, "paths need to start with /"
end
+
location = location.chomp('/')
match = Regexp.new("^#{Regexp.quote(location).gsub('/', '/+')}(.*)", nil, 'n')
[host, location, match, app]
- }.sort_by(&longest_path_first)
+ }.sort_by do |(host, location, _, _)|
+ [host ? -host.size : NEGATIVE_INFINITY, -location.size]
+ end
end
def call(env)
path = env["PATH_INFO"]
script_name = env['SCRIPT_NAME']
- hHost, sName, sPort = env.values_at('HTTP_HOST','SERVER_NAME','SERVER_PORT')
- @mapping.each { |host, location, match, app|
- next unless (hHost == host || sName == host \
- || (host.nil? && (hHost == sName || hHost == sName+':'+sPort)))
- next unless path.to_s =~ match && rest = $1
- next unless rest.empty? || rest[0] == ?/
- env.merge!('SCRIPT_NAME' => (script_name + location), 'PATH_INFO' => rest)
+ hHost = env['HTTP_HOST']
+ sName = env['SERVER_NAME']
+ sPort = env['SERVER_PORT']
+
+ @mapping.each do |host, location, match, app|
+ unless hHost == host \
+ || sName == host \
+ || (!host && (hHost == sName || hHost == sName+':'+sPort))
+ next
+ end
+
+ next unless m = match.match(path.to_s)
+
+ rest = m[1]
+ next unless !rest || rest.empty? || rest[0] == ?/
+
+ env['SCRIPT_NAME'] = (script_name + location)
+ env['PATH_INFO'] = rest
+
return app.call(env)
- }
+ end
+
[404, {"Content-Type" => "text/plain", "X-Cascade" => "pass"}, ["Not Found: #{path}"]]
+
ensure
- env.merge! 'PATH_INFO' => path, 'SCRIPT_NAME' => script_name
+ env['PATH_INFO'] = path
+ env['SCRIPT_NAME'] = script_name
end
end
end
Please sign in to comment.
Something went wrong with that request. Please try again.