1 """Wrapper for mod_python, for use as a CherryPy HTTP server.
2
3 To autostart modpython, 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.
7
8 If you wish to use the WSGI interface instead of our _cpmodpy interface,
9 you also need the 'modpython_gateway' module at:
10 http://projects.amor.org/misc/wiki/ModPythonGateway
11
12
13 KNOWN BUGS
14 ==========
15
16 1. Apache processes Range headers automatically; CherryPy's truncated
17 output is then truncated again by Apache. See test_core.testRanges.
18 This was worked around in http://www.cherrypy.org/changeset/1319.
19 2. Apache does not allow custom HTTP methods like CONNECT as per the spec.
20 See test_core.testHTTPMethods.
21 3. Max request header and body settings do not work with Apache.
22 4. Apache replaces status "reason phrases" automatically. For example,
23 CherryPy may set "304 Not modified" but Apache will write out
24 "304 Not Modified" (capital "M").
25 5. Apache does not allow custom error codes as per the spec.
26 6. Apache (or perhaps modpython, or modpython_gateway) unquotes %xx in the
27 Request-URI too early.
28 7. mod_python will not read request bodies which use the "chunked"
29 transfer-coding (it passes REQUEST_CHUNKED_ERROR to ap_setup_client_block
30 instead of REQUEST_CHUNKED_DECHUNK, see Apache2's http_protocol.c and
31 mod_python's requestobject.c).
32 """
33
34 import os
35 curdir = os.path.join(os.getcwd(), os.path.dirname(__file__))
36 import re
37 import time
38
39 from cherrypy.test import test
40
41
43 pipein, pipeout = os.popen4("%s %s" % (cmd, args))
44 try:
45 firstline = pipeout.readline()
46 if (re.search(r"(not recognized|No such file|not found)", firstline,
47 re.IGNORECASE)):
48 raise IOError('%s must be on your system path.' % cmd)
49 output = firstline + pipeout.read()
50 finally:
51 pipeout.close()
52 return output
53
54
55 APACHE_PATH = "apache"
56 CONF_PATH = "test_mp.conf"
57
58 conf_modpython_gateway = """
59 # Apache2 server conf file for testing CherryPy with modpython_gateway.
60
61 DocumentRoot "/"
62 Listen %s
63 LoadModule python_module modules/mod_python.so
64
65 SetHandler python-program
66 PythonFixupHandler cherrypy.test.modpy::wsgisetup
67 PythonOption testmod %s
68 PythonHandler modpython_gateway::handler
69 PythonOption wsgi.application cherrypy::tree
70 PythonDebug On
71 """
72
73 conf_cpmodpy = """
74 # Apache2 server conf file for testing CherryPy with _cpmodpy.
75
76 DocumentRoot "/"
77 Listen %s
78 LoadModule python_module modules/mod_python.so
79
80 SetHandler python-program
81 PythonHandler cherrypy._cpmodpy::handler
82 PythonOption cherrypy.setup cherrypy.test.%s::setup_server
83 PythonDebug On
84 """
85
86 -def start(testmod, port, conf_template):
87 mpconf = CONF_PATH
88 if not os.path.isabs(mpconf):
89 mpconf = os.path.join(curdir, mpconf)
90
91 f = open(mpconf, 'wb')
92 try:
93 f.write(conf_template % (port, testmod))
94 finally:
95 f.close()
96
97 result = read_process(APACHE_PATH, "-k start -f %s" % mpconf)
98 if result:
99 print result
100
104
105
106 loaded = False
108 global loaded
109 if not loaded:
110 loaded = True
111 options = req.get_options()
112 modname = options['testmod']
113 mod = __import__(modname, globals(), locals(), [''])
114 mod.setup_server()
115
116 import cherrypy
117 cherrypy.config.update({
118 "log.error_file": os.path.join(curdir, "test.log"),
119 "environment": "production",
120 })
121 cherrypy.engine.start(blocking=False)
122 from mod_python import apache
123 return apache.OK
124
125
127 """TestHarness for ModPython and CherryPy."""
128
129 use_wsgi = False
130
131 - def _run(self, conf):
162