module Jangle class HashEndpointRouter def initialize(routes) @routes = routes end # Consumes the parts of the request path, finding the next hash # or an endpoint; returns the endpoint identified by that sequence of path parts # # For example, the hash might look like this: # {'base' => { # 'one' => HttpEndpoint.new(:host => 'localhost', :port => 8080), # 'two' => HttpEndpoint.new(:host => 'localhost', :port => 4000) # }, # 'other' => { # 'three' => HttpEndpoint.new(:host => 'localhost') # } # } # # which would be able to route /base/one, /base/two, /other/three to those three # endpoints def route(request) path_parts = request.path_info.split('/') path_parts.shift if path_parts.empty? path_remaining = '/' service = @routes['_root_'] else path_parts_remaining, service = do_routing(@routes, path_parts) path_remaining = '/' + path_parts_remaining.join('/') end return [path_remaining, service] end private def do_routing(route_or_dest, path_parts) while route_or_dest.respond_to?(:has_key?) and route_or_dest.has_key?(path_parts[0]) route_or_dest = route_or_dest[path_parts.shift] end if route_or_dest.respond_to?(:serve) service = route_or_dest else service = route_or_dest['_root_'] end [path_parts, service] end end end