forked from nicferrier/multiserver
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ms.py
100 lines (78 loc) · 2.75 KB
/
ms.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
#!/usr/bin/python
"""
MultiServer
This is a simple wsgi server that does virtual host handling across a
directory of python modules.
This can use a config variable wsgi_path to find the modules. The path
can be specified in a config file: ~/.mswsgi.conf
[Server]
wsgi_path = ...
The python module loaded is defined in the config file:
[Server]
module_name = ...
The module is imported by it's name. A function 'dispatch' is
expected.
Reference for the config file:
module_name the module name used to do the dispatching.
wsgi_path where to find server instances
port the port to start the multiserver on (default: 9001)
"""
import re
import os
from os.path import join as joinpath
def multiwsgidispatch(wsgi_path, module_name):
"""Get a wsgi handler to do multiple dispatch.
The handler uses the Host header to try to find a matching wsgi
instance in the config['wsgi_path']
"""
m = __import__(module_name, {}, {}, [""])
def wsgi_dispatcher(environ, start_response):
"""Virtual host WSGI dispatcher"""
host = environ["HTTP_HOST"]
targetpart = host.split(".")[0]
# Make a regex that will match against targets
target_re = re.compile("%s.*" % re.sub("-", "[_-]", targetpart))
for entry in os.listdir(wsgi_path):
if target_re.match(entry):
try:
path = joinpath(wsgi_path, entry)
return m.dispatch(path, environ, start_response)
except Exception,e:
start_response('500 Error', [('content-type', 'text/html')])
return ["<p>Error: %s</p>" % e]
# Otherwise it's an error
start_response('500 Error', [('content-type', 'text/html')])
return ["<p>No target found for %s</p>" % host]
return wsgi_dispatcher
# Config stuff
from ConfigParser import ConfigParser
from os.path import expanduser
import wsgiref.simple_server
RealServerHandler = wsgiref.simple_server.ServerHandler
class MServerHandler(RealServerHandler):
def __init__(self, stdin, stdout, stderr, environ):
RealServerHandler.__init__(
self,
stdin, stdout, stderr, environ,
multithread=False,
multiprocess=True
)
def main():
conf = ConfigParser({"port": "9001"})
try:
conf.read(expanduser("~/.mswsgi.conf"))
except:
pass
wsgiref.simple_server.ServerHandler = MServerHandler
s = wsgiref.simple_server.make_server(
"localhost",
int(conf.get("Server", "port")),
multiwsgidispatch(
conf.get("Server", "wsgi_path"),
conf.get("Server", "module_name")
),
)
s.serve_forever()
if __name__ == "__main__":
main()
# End