dirplex: Plugged a memory leak.
[ashd.git] / python / ashd / wsgidir.py
CommitLineData
c06db49a
FT
1import os, threading, types
2import wsgiutil
3
14ef1e0e
FT
4class cachedmod:
5 def __init__(self, mod, mtime):
6 self.lock = threading.Lock()
7 self.mod = mod
8 self.mtime = mtime
9
c06db49a
FT
10exts = {}
11modcache = {}
12cachelock = threading.Lock()
13
14def mangle(path):
15 ret = ""
16 for c in path:
17 if c.isalnum():
18 ret += c
19 else:
20 ret += "_"
21 return ret
22
23def getmod(path):
24 sb = os.stat(path)
25 cachelock.acquire()
26 try:
27 if path in modcache:
14ef1e0e
FT
28 entry = modcache[path]
29 if sb.st_mtime <= entry.mtime:
30 return entry
31
c06db49a
FT
32 f = open(path)
33 try:
34 text = f.read()
35 finally:
36 f.close()
37 code = compile(text, path, "exec")
38 mod = types.ModuleType(mangle(path))
39 mod.__file__ = path
40 exec code in mod.__dict__
14ef1e0e
FT
41 entry = cachedmod(mod, sb.st_mtime)
42 modcache[path] = entry
43 return entry
c06db49a
FT
44 finally:
45 cachelock.release()
46
47def chain(path, env, startreq):
48 mod = getmod(path)
14ef1e0e
FT
49 entry = None
50 if mod is not None:
51 mod.lock.acquire()
52 try:
53 if hasattr(mod, "entry"):
54 entry = mod.entry
55 else:
56 if hasattr(mod.mod, "wmain"):
adb11d5f 57 entry = mod.mod.wmain()
14ef1e0e
FT
58 elif hasattr(mod.mod, "application"):
59 entry = mod.mod.application
60 mod.entry = entry
61 finally:
62 mod.lock.release()
63 if entry is not None:
64 return entry(env, startreq)
36ea06a6 65 return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "Invalid WSGI handler.")
c06db49a
FT
66exts["wsgi"] = chain
67
48a91dd9
FT
68def addext(ext, handler):
69 p = handler.rindex('.')
70 mname = handler[:p]
71 hname = handler[p + 1:]
72 mod = __import__(mname, fromlist = ["dummy"])
73 exts[ext] = getattr(mod, hname)
74
c06db49a
FT
75def application(env, startreq):
76 if not "SCRIPT_FILENAME" in env:
36ea06a6 77 return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
c06db49a
FT
78 path = env["SCRIPT_FILENAME"]
79 base = os.path.basename(path)
80 p = base.rfind('.')
81 if p < 0 or not os.access(path, os.R_OK):
36ea06a6 82 return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
c06db49a
FT
83 ext = base[p + 1:]
84 if not ext in exts:
36ea06a6 85 return wsgiutil.simpleerror(env, startreq, 500, "Internal Error", "The server is erroneously configured.")
c06db49a
FT
86 return(exts[ext](path, env, startreq))
87
adb11d5f 88def wmain(*argv):
48a91dd9
FT
89 for arg in argv:
90 if arg[0] == '.':
91 p = arg.index('=')
92 addext(arg[1:p], arg[p + 1:])
c06db49a 93 return application