212c4b73ef4ca20a2bd1e486e42ac2b5851da4d7
[ashd.git] / python / ashd / wsgidir.py
1 import os, threading, types
2 import wsgiutil
3
4 exts = {}
5 modcache = {}
6 cachelock = threading.Lock()
7
8 def mangle(path):
9     ret = ""
10     for c in path:
11         if c.isalnum():
12             ret += c
13         else:
14             ret += "_"
15     return ret
16
17 def getmod(path):
18     sb = os.stat(path)
19     cachelock.acquire()
20     try:
21         if path in modcache:
22             mod, mtime = modcache[path]
23             if sb.st_mtime <= mtime:
24                 return mod
25         f = open(path)
26         try:
27             text = f.read()
28         finally:
29             f.close()
30         code = compile(text, path, "exec")
31         mod = types.ModuleType(mangle(path))
32         mod.__file__ = path
33         exec code in mod.__dict__
34         modcache[path] = mod, sb.st_mtime
35         return mod
36     finally:
37         cachelock.release()
38
39 def chain(path, env, startreq):
40     mod = getmod(path)
41     if hasattr(mod, "wmain"):
42         return (mod.wmain())(env, startreq)
43     elif hasattr(mod, "application"):
44         return mod.application(env, startreq)
45     return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "Invalid WSGI handler.")
46 exts["wsgi"] = chain
47
48 def application(env, startreq):
49     if not "SCRIPT_FILENAME" in env:
50         return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
51     path = env["SCRIPT_FILENAME"]
52     base = os.path.basename(path)
53     p = base.rfind('.')
54     if p < 0 or not os.access(path, os.R_OK):
55         return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
56     ext = base[p + 1:]
57     if not ext in exts:
58         return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
59     return(exts[ext](path, env, startreq))
60
61 def wmain(argv):
62     return application