"""Native adapter for serving CherryPy via mod_python"""frommod_pythonimportapacheimportcherrypyfromcherrypy._cperrorimportformat_exc,bare_errorfromcherrypy.libimporthttpdefsetup(req):# Run any setup function defined by a "PythonOption cherrypy.setup" directive.options=req.get_options()if'cherrypy.setup'inoptions:modname,fname=options['cherrypy.setup'].split('::')mod=__import__(modname,globals(),locals(),[fname])func=getattr(mod,fname)func()cherrypy.config.update({'global':{'log_to_screen':False}})ifcherrypy.engine.state==cherrypy._cpengine.STOPPED:cherrypy.engine.start(blocking=False)elifcherrypy.engine.state==cherrypy._cpengine.STARTING:cherrypy.engine.wait()defcherrypy_cleanup(data):cherrypy.engine.stop()try:# apache.register_cleanup wasn't available until 3.1.4.apache.register_cleanup(cherrypy_cleanup)exceptAttributeError:req.server.register_cleanup(req,cherrypy_cleanup)class_ReadOnlyRequest:expose=('read','readline','readlines')def__init__(self,req):formethodinself.expose:self.__dict__[method]=getattr(req,method)_isSetUp=Falsedefhandler(req):try:global_isSetUpifnot_isSetUp:setup(req)_isSetUp=True# Obtain a Request object from CherryPylocal=req.connection.local_addrlocal=http.Host(local[0],local[1],req.connection.local_hostor"")remote=req.connection.remote_addrremote=http.Host(remote[0],remote[1],req.connection.remote_hostor"")scheme=req.parsed_uri[0]or'http'request=cherrypy.engine.request(local,remote,scheme)req.get_basic_auth_pw()request.login=req.usertry:# apache.mpm_query only became available in mod_python 3.1q=apache.mpm_querythreaded=q(apache.AP_MPMQ_IS_THREADED)forked=q(apache.AP_MPMQ_IS_FORKED)exceptAttributeError:bad_value=("You must provide a PythonOption '%s', ""either 'on' or 'off', when running a version ""of mod_python < 3.1")threaded=options.get('multithread','').lower()ifthreaded=='on':threaded=Trueelifthreaded=='off':threaded=Falseelse:raiseValueError(bad_value%"multithread")forked=options.get('multiprocess','').lower()ifforked=='on':forked=Trueelifforked=='off':forked=Falseelse:raiseValueError(bad_value%"multiprocess")request.multithread=bool(threaded)request.multiprocess=bool(forked)# Run the CherryPy Request object and obtain the responseheaders=req.headers_in.items()rfile=_ReadOnlyRequest(req)response=request.run(req.method,req.uri,req.argsor"",req.protocol,headers,rfile)send_response(req,response.status,response.header_list,response.body)request.close()except:tb=format_exc()cherrypy.log(tb)s,h,b=bare_error()send_response(req,s,h,b)returnapache.OKdefsend_response(req,status,headers,body):# Set response statusreq.status=int(status[:3])# Set response headersreq.content_type="text/plain"forheader,valueinheaders:ifheader.lower()=='content-type':req.content_type=valuecontinuereq.headers_out.add(header,value)# Set response bodyifisinstance(body,basestring):req.write(body)else:forseginbody:req.write(seg)