Fixed python_path problem.
[smonitor.git] / lib / cherrypy / test / modwsgi.py
blob309a541c7b3ddb7a98ba64c1ec81a8c1263ceb96
1 """Wrapper for mod_wsgi, for use as a CherryPy HTTP server.
3 To autostart modwsgi, the "apache" executable or script must be
4 on your system path, or you must override the global APACHE_PATH.
5 On some platforms, "apache" may be called "apachectl" or "apache2ctl"--
6 create a symlink to them if needed.
9 KNOWN BUGS
10 ==========
12 ##1. Apache processes Range headers automatically; CherryPy's truncated
13 ## output is then truncated again by Apache. See test_core.testRanges.
14 ## This was worked around in http://www.cherrypy.org/changeset/1319.
15 2. Apache does not allow custom HTTP methods like CONNECT as per the spec.
16 See test_core.testHTTPMethods.
17 3. Max request header and body settings do not work with Apache.
18 ##4. Apache replaces status "reason phrases" automatically. For example,
19 ## CherryPy may set "304 Not modified" but Apache will write out
20 ## "304 Not Modified" (capital "M").
21 ##5. Apache does not allow custom error codes as per the spec.
22 ##6. Apache (or perhaps modpython, or modpython_gateway) unquotes %xx in the
23 ## Request-URI too early.
24 7. mod_wsgi will not read request bodies which use the "chunked"
25 transfer-coding (it passes REQUEST_CHUNKED_ERROR to ap_setup_client_block
26 instead of REQUEST_CHUNKED_DECHUNK, see Apache2's http_protocol.c and
27 mod_python's requestobject.c).
28 8. When responding with 204 No Content, mod_wsgi adds a Content-Length
29 header for you.
30 9. When an error is raised, mod_wsgi has no facility for printing a
31 traceback as the response content (it's sent to the Apache log instead).
32 10. Startup and shutdown of Apache when running mod_wsgi seems slow.
33 """
35 import os
36 curdir = os.path.abspath(os.path.dirname(__file__))
37 import re
38 import sys
39 import time
41 import cherrypy
42 from cherrypy.test import helper, webtest
45 def read_process(cmd, args=""):
46 pipein, pipeout = os.popen4("%s %s" % (cmd, args))
47 try:
48 firstline = pipeout.readline()
49 if (re.search(r"(not recognized|No such file|not found)", firstline,
50 re.IGNORECASE)):
51 raise IOError('%s must be on your system path.' % cmd)
52 output = firstline + pipeout.read()
53 finally:
54 pipeout.close()
55 return output
58 if sys.platform == 'win32':
59 APACHE_PATH = "httpd"
60 else:
61 APACHE_PATH = "apache"
63 CONF_PATH = "test_mw.conf"
65 conf_modwsgi = r"""
66 # Apache2 server conf file for testing CherryPy with modpython_gateway.
68 ServerName 127.0.0.1
69 DocumentRoot "/"
70 Listen %(port)s
72 AllowEncodedSlashes On
73 LoadModule rewrite_module modules/mod_rewrite.so
74 RewriteEngine on
75 RewriteMap escaping int:escape
77 LoadModule log_config_module modules/mod_log_config.so
78 LogFormat "%%h %%l %%u %%t \"%%r\" %%>s %%b \"%%{Referer}i\" \"%%{User-agent}i\"" combined
79 CustomLog "%(curdir)s/apache.access.log" combined
80 ErrorLog "%(curdir)s/apache.error.log"
81 LogLevel debug
83 LoadModule wsgi_module modules/mod_wsgi.so
84 LoadModule env_module modules/mod_env.so
86 WSGIScriptAlias / "%(curdir)s/modwsgi.py"
87 SetEnv testmod %(testmod)s
88 """
91 class ModWSGISupervisor(helper.Supervisor):
92 """Server Controller for ModWSGI and CherryPy."""
94 using_apache = True
95 using_wsgi = True
96 template=conf_modwsgi
98 def __str__(self):
99 return "ModWSGI Server on %s:%s" % (self.host, self.port)
101 def start(self, modulename):
102 mpconf = CONF_PATH
103 if not os.path.isabs(mpconf):
104 mpconf = os.path.join(curdir, mpconf)
106 f = open(mpconf, 'wb')
107 try:
108 output = (self.template %
109 {'port': self.port, 'testmod': modulename,
110 'curdir': curdir})
111 f.write(output)
112 finally:
113 f.close()
115 result = read_process(APACHE_PATH, "-k start -f %s" % mpconf)
116 if result:
117 print(result)
119 # Make a request so mod_wsgi starts up our app.
120 # If we don't, concurrent initial requests will 404.
121 cherrypy._cpserver.wait_for_occupied_port("127.0.0.1", self.port)
122 webtest.openURL('/ihopetheresnodefault', port=self.port)
123 time.sleep(1)
125 def stop(self):
126 """Gracefully shutdown a server that is serving forever."""
127 read_process(APACHE_PATH, "-k stop")
130 loaded = False
131 def application(environ, start_response):
132 import cherrypy
133 global loaded
134 if not loaded:
135 loaded = True
136 modname = "cherrypy.test." + environ['testmod']
137 mod = __import__(modname, globals(), locals(), [''])
138 mod.setup_server()
140 cherrypy.config.update({
141 "log.error_file": os.path.join(curdir, "test.error.log"),
142 "log.access_file": os.path.join(curdir, "test.access.log"),
143 "environment": "test_suite",
144 "engine.SIGHUP": None,
145 "engine.SIGTERM": None,
147 return cherrypy.tree(environ, start_response)