Changeset 39
- Timestamp:
- 02/09/06 03:37:48
- Files:
-
- modpython_gateway.py (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
modpython_gateway.py
r37 r39 7 7 <Location /mcontrol> 8 8 SetHandler python-program 9 PythonHandler wsgiref.modpy_wrapper::handler10 PythonOption application cherrypy. wsgiapp::wsgiApp9 PythonHandler modpython_gateway::handler 10 PythonOption application cherrypy._cpwsgi::wsgiApp 11 11 PythonOption import mcontrol.cherry::startup 12 12 </Location> … … 15 15 always be equal to "the root URL of the app"; Apache probably won't act as 16 16 you expect in that case. You can add another PythonOption directive to tell 17 themodpython_gateway to force that behavior:17 modpython_gateway to force that behavior: 18 18 19 19 PythonOption SCRIPT_NAME /mcontrol … … 21 21 """ 22 22 23 import sys 23 import traceback 24 24 25 from mod_python import apache 25 from wsgiref.handlers import BaseCGIHandler26 26 27 27 … … 70 70 "when running a version of mod_python < 3.1") 71 71 72 class Handler(BaseCGIHandler): 72 73 class Handler: 73 74 74 75 def __init__(self, req): 76 self.started = False 77 75 78 options = req.get_options() 76 79 … … 78 81 try: 79 82 q = apache.mpm_query 83 threaded = q(apache.AP_MPMQ_IS_THREADED) 84 forked = q(apache.AP_MPMQ_IS_FORKED) 80 85 except AttributeError: 81 86 threaded = options.get('multithread', '').lower() … … 94 99 else: 95 100 raise ValueError(bad_value % "multiprocess") 96 else: 97 threaded = q(apache.AP_MPMQ_IS_THREADED) 98 forked = q(apache.AP_MPMQ_IS_FORKED) 99 100 env = dict(apache.build_cgi_env(req)) 101 102 env = self.environ = dict(apache.build_cgi_env(req)) 101 103 102 104 if 'SCRIPT_NAME' in options: 105 # Override SCRIPT_NAME and PATH_INFO if requested. 103 106 env['SCRIPT_NAME'] = options['SCRIPT_NAME'] 104 107 env['PATH_INFO'] = req.uri[len(options['SCRIPT_NAME']):] 105 108 106 BaseCGIHandler.__init__(self, 107 stdin=InputWrapper(req), 108 stdout=None, 109 stderr=ErrorWrapper(req), 110 environ=env, 111 multiprocess=forked, 112 multithread=threaded 113 ) 109 env['wsgi.input'] = InputWrapper(req) 110 env['wsgi.errors'] = ErrorWrapper(req) 111 env['wsgi.version'] = (1,0) 112 env['wsgi.run_once'] = False 113 if env.get("HTTPS") in ('yes', 'on', '1'): 114 env['wsgi.url_scheme'] = 'https' 115 else: 116 env['wsgi.url_scheme'] = 'http' 117 env['wsgi.multithread'] = threaded 118 env['wsgi.multiprocess'] = forked 119 114 120 self.request = req 115 self._write = req.write 116 117 def _flush(self): 118 pass 119 120 def send_headers(self): 121 self.cleanup_headers() 122 self.headers_sent = True 123 # Can't just return 200 or the page will hang until timeout 124 self.request.status = int(self.status[:3]) 125 # the headers.Headers class doesn't have an iteritems method... 126 for key, val in self.headers.items(): 121 122 def run(self, application): 123 try: 124 result = application(self.environ, self.start_response) 125 for data in result: 126 self.write(data) 127 if not self.started: 128 self.request.set_content_length(0) 129 if hasattr(result, 'close'): 130 result.close() 131 except: 132 traceback.print_exc(None, self.environ['wsgi.errors']) 133 if not self.started: 134 self.request.status = 500 135 self.request.content_type = 'text/plain' 136 data = "A server error occurred. Please contact the administrator." 137 self.request.set_content_length(len(data)) 138 self.request.write(data) 139 140 def start_response(self, status, headers, exc_info=None): 141 if exc_info: 142 try: 143 if self.started: 144 raise exc_info[0], exc_info[1], exc_info[2] 145 finally: 146 exc_info = None 147 148 self.request.status = int(status[:3]) 149 150 for key, val in headers: 127 151 if key.lower() == 'content-length': 128 if val is not None: 129 self.request.set_content_length(int(val)) 152 self.request.set_content_length(int(val)) 130 153 elif key.lower() == 'content-type': 131 154 self.request.content_type = val 132 155 else: 133 self.request.headers_out[key] = val 156 self.request.headers_out.add(key, val) 157 158 return self.write 159 160 def write(self, data): 161 if not self.started: 162 self.started = True 163 self.request.write(data) 134 164 135 165 … … 137 167 138 168 def profile(req): 139 # Call this function instead of handler169 # Call this function instead of "handler" 140 170 # to get profiling data for each call. 141 171 import hotshot, os.path 142 ppath = os.path.dirname(__file__)143 if not os.path.exists(ppath):144 os.makedirs(ppath)145 172 global _counter 146 173 _counter += 1 147 ppath = os.path.join( ppath, "cp_%s.prof" % _counter)174 ppath = os.path.join(os.path.dirname(__file__), "cp_%s.prof" % _counter) 148 175 prof = hotshot.Profile(ppath) 149 result =prof.runcall(handler, req)176 prof.runcall(handler, req) 150 177 prof.close() 151 return result178 return apache.OK 152 179 153 180 def handler(req): 181 # If you use a PythonImport directive as recommended, its interpreter_name 182 # value must EXACTLY match the value of req.interpreter (case-sensitive). 183 # You can un-comment the next line to get the value of req.interpreter. 184 ## raise StandardError(repr(req.interpreter)) 185 154 186 config = req.get_config() 155 187 debug = int(config.get("PythonDebug", 0)) … … 177 209 module = __import__(modname, globals(), locals(), ['']) 178 210 app = getattr(module, objname) 179 180 ## modname, objname = options['application'].split('::') 181 ## module = apache.import_module(modname, autoreload=False, log=debug) 182 ## app = apache.resolve_object(module, objname, arg=None, silent=False) 183 184 # You can un-comment the next line to get the value of req.interpreter. 185 # If you use a PythonImport directive as recommended, its interpreter_name 186 # value must EXACTLY match the value of req.interpreter (case-sensitive). 187 ## raise StandardError(repr(req.interpreter)) 188 189 h = Handler(req) 190 ## from paste import lint 191 ## app = lint.middleware(app) 192 h.run(app) 193 194 # status was set in Handler.send_headers(); always return apache.OK 211 Handler(req).run(app) 212 213 # status was set in Handler; always return apache.OK 195 214 return apache.OK 196 215
