require 'rubygems' require 'metaid' require 'serverside' # This can be mixed into any class to make it routable. module Routable # Routes a request. def route(req) if leaf = find_leaf(req, req.uri) leaf.render(req) else raise "Invalid route (#{req.uri})" end end # Finds a leaf recursively. def find_leaf(req, path) if path =~ /^\/([^\/]+)(.*)$/ leaf = child_leaf(req, $1.to_sym).find_leaf(req, $2) else self end rescue nil end # stock implementation. Finds a child leaf by name (name should be a symbol) def child_leaf(request, name) @child_leaves ? @child_leaves[name] : nil end # stock implementation. Returns a hash of all child leaves. def child_leaves @child_leaves || {} end # stock implementation. Adds a child leaf. def add_leaf(name, leaf) @child_leaves ||= {} @child_leaves[name] = leaf end end class Leaf include Routable def initialize(&block) if block meta_def(:render, &block) end end def render(req) req.send_representation(200, 'text/html', "

#{req.uri}

") end end server = ServerSide::HTTP::Server.new do $root = Leaf.new def handle $root.route(self) end end l = Leaf.new do |req| req.send_representation(200, 'text/html', 'this is abc') end $root.add_leaf(:abc, l) trap('INT') {exit} puts "Serving on port 8000..." server.start('0.0.0.0', 8000)