require 'rack'
if ARGV.size > 0 then
Dir.chdir ARGV[0]
end
def add_server(dir)
def read_field (dir, field, default)
file = File.join(dir, field)
if File.exists? file then
File.open(file).read.chomp
else
default
end
end
return [{
:path => read_field(dir, "path", "*"),
:domain => read_field(dir, "domain", "*"),
:host => read_field(dir, "host", "localhost"),
:port => read_field(dir, "port", "80"),
:mode => read_field(dir, "mode", "http"),
:path => read_field(dir, "path", "/dev/null"),
}]
end
def match(spec, str)
stack = [[0,0]]
while not stack.empty? do
i, j = stack.pop
if i >= spec.size and j >= str.size then
return true
elsif i >= spec.size or j >= str.size then
next
elsif spec[i] == '*' then
stack.push([ i, j+1 ])
stack.push([ i+1, j+1 ])
elsif spec[i] == str[j] then
stack.push([ i+1, j+1 ])
end
end
return false
end
def init_paths
ss = Dir.new(Dir.pwd).sort.map do |f|
unless f.start_with? "." then
add_server(f)
else
[]
end
end
return ss.flatten
end
def find_server(env, paths)
paths.each do |s|
if match(s[:path], env['PATH_INFO']) and match(s[:domain], env['SERVER_NAME']) then
if s[:mode] == "http" then
return [ 200, { 'Content-Type' => 'text/html'},
[ "Forwarding to #{s[:mode]}://#{s[:host]}:#{s[:port]}" ] ]
elsif s[:mode] == "aloys" then
return [ 200, { 'Content-Type' => 'text/html'}
[ "Deferring to aloys dir at #{s[:path]}" ] ]
end
end
end
return [ 500, { 'Content-Type' => 'text/html' },
[ "Unable to find server to forward to" ] ]
end
def serve_paths(paths)
app = Proc.new do |env|
find_server(env, paths)
end
Rack::Handler::WEBrick.run app
end
serve_paths(init_paths)