gdritter repos httputils / 05175a4
prototype server Getty Ritter 8 years ago
6 changed file(s) with 78 addition(s) and 0 deletion(s). Collapse all Expand all
1 require 'rack'
2
3 if ARGV.size > 0 then
4 Dir.chdir ARGV[0]
5 end
6
7 def add_server(dir)
8 def read_field (dir, field, default)
9 file = File.join(dir, field)
10 if File.exists? file then
11 File.open(file).read.chomp
12 else
13 default
14 end
15 end
16
17 return [{
18 :path => read_field(dir, "path", "*"),
19 :domain => read_field(dir, "domain", "*"),
20 :host => read_field(dir, "host", "localhost"),
21 :port => read_field(dir, "port", "80"),
22 :mode => read_field(dir, "mode", "http"),
23 }]
24 end
25
26 def match(spec, str)
27 stack = [[0,0]]
28 while not stack.empty? do
29 i, j = stack.pop
30 if i >= spec.size and j >= str.size then
31 return true
32 elsif i >= spec.size or j >= str.size then
33 next
34 elsif spec[i] == '*' then
35 stack.push([ i, j+1 ])
36 stack.push([ i+1, j+1 ])
37 elsif spec[i] == str[j] then
38 stack.push([ i+1, j+1 ])
39 end
40 end
41 return false
42 end
43
44 def init_paths
45 ss = Dir.new(Dir.pwd).sort.map do |f|
46 unless f.start_with? "." then
47 add_server(f)
48 else
49 []
50 end
51 end
52 return ss.flatten
53 end
54
55 def find_server(env, paths)
56 paths.each do |s|
57 if match(s[:path], env['PATH_INFO']) and match(s[:domain], env['SERVER_NAME']) then
58 return [ 200, { 'Content-Type' => 'text/html'},
59 [ "Forwarding to #{s[:mode]}://#{s[:host]}:#{s[:port]}" ] ]
60 end
61 end
62 return [ 500, { 'Content-Type' => 'text/html' },
63 [ "Unable to find server to forward to" ] ]
64 end
65
66 def serve_paths(paths)
67 app = Proc.new do |env|
68 find_server(env, paths)
69 end
70 Rack::Handler::WEBrick.run app
71 end
72
73 serve_paths(init_paths)
1 gdritter.com