"""Native adapter for serving CherryPy via its builtin server."""importloggingimportsysimportcherrypyfromcherrypy._cpcompatimportBytesIOfromcherrypy._cperrorimportformat_exc,bare_errorfromcherrypy.libimporthttputilfromcherrypyimportwsgiserverclassNativeGateway(wsgiserver.Gateway):recursive=Falsedefrespond(self):req=self.reqtry:# Obtain a Request object from CherryPylocal=req.server.bind_addrlocal=httputil.Host(local[0],local[1],"")remote=req.conn.remote_addr,req.conn.remote_portremote=httputil.Host(remote[0],remote[1],"")scheme=req.schemesn=cherrypy.tree.script_name(req.urior"/")ifsnisNone:self.send_response('404 Not Found',[],[''])else:app=cherrypy.tree.apps[sn]method=req.methodpath=req.pathqs=req.qsor""headers=req.inheaders.items()rfile=req.rfileprev=Nonetry:redirections=[]whileTrue:request,response=app.get_serving(local,remote,scheme,"HTTP/1.1")request.multithread=Truerequest.multiprocess=Falserequest.app=apprequest.prev=prev# Run the CherryPy Request object and obtain the responsetry:request.run(method,path,qs,req.request_protocol,headers,rfile)breakexceptcherrypy.InternalRedirect:ir=sys.exc_info()[1]app.release_serving()prev=requestifnotself.recursive:ifir.pathinredirections:raiseRuntimeError("InternalRedirector visited the ""same URL twice: %r"%ir.path)else:# Add the *previous* path_info + qs to redirections.ifqs:qs="?"+qsredirections.append(sn+path+qs)# Munge environment and try again.method="GET"path=ir.pathqs=ir.query_stringrfile=BytesIO()self.send_response(response.output_status,response.header_list,response.body)finally:app.release_serving()except:tb=format_exc()#print tbcherrypy.log(tb,'NATIVE_ADAPTER',severity=logging.ERROR)s,h,b=bare_error()self.send_response(s,h,b)defsend_response(self,status,headers,body):req=self.req# Set response statusreq.status=str(statusor"500 Server Error")# Set response headersforheader,valueinheaders:req.outheaders.append((header,value))if(req.readyandnotreq.sent_headers):req.sent_headers=Truereq.send_headers()# Set response bodyforseginbody:req.write(seg)classCPHTTPServer(wsgiserver.HTTPServer):"""Wrapper for wsgiserver.HTTPServer. wsgiserver has been designed to not reference CherryPy in any way, so that it can be used in other frameworks and applications. Therefore, we wrap it here, so we can apply some attributes from config -> cherrypy.server -> HTTPServer. """def__init__(self,server_adapter=cherrypy.server):self.server_adapter=server_adapterserver_name=(self.server_adapter.socket_hostorself.server_adapter.socket_fileorNone)wsgiserver.HTTPServer.__init__(self,server_adapter.bind_addr,NativeGateway,minthreads=server_adapter.thread_pool,maxthreads=server_adapter.thread_pool_max,server_name=server_name)self.max_request_header_size=self.server_adapter.max_request_header_sizeor0self.max_request_body_size=self.server_adapter.max_request_body_sizeor0self.request_queue_size=self.server_adapter.socket_queue_sizeself.timeout=self.server_adapter.socket_timeoutself.shutdown_timeout=self.server_adapter.shutdown_timeoutself.protocol=self.server_adapter.protocol_versionself.nodelay=self.server_adapter.nodelayssl_module=self.server_adapter.ssl_moduleor'pyopenssl'ifself.server_adapter.ssl_context:adapter_class=wsgiserver.get_ssl_adapter_class(ssl_module)self.ssl_adapter=adapter_class(self.server_adapter.ssl_certificate,self.server_adapter.ssl_private_key,self.server_adapter.ssl_certificate_chain)self.ssl_adapter.context=self.server_adapter.ssl_contextelifself.server_adapter.ssl_certificate:adapter_class=wsgiserver.get_ssl_adapter_class(ssl_module)self.ssl_adapter=adapter_class(self.server_adapter.ssl_certificate,self.server_adapter.ssl_private_key,self.server_adapter.ssl_certificate_chain)