mirror of
https://github.com/evilhero/mylar
synced 2024-12-26 01:26:50 +00:00
69eeb9b49d
Update bs4 to latest version to fix issues Get clean modules using `pip install --upgrade --target=lib` Move cherrypy, mako, pystun, bs4 into lib directory
149 lines
5.9 KiB
Python
Executable file
149 lines
5.9 KiB
Python
Executable file
"""Native adapter for serving CherryPy via its builtin server."""
|
|
|
|
import logging
|
|
import sys
|
|
|
|
import cherrypy
|
|
from cherrypy._cpcompat import BytesIO
|
|
from cherrypy._cperror import format_exc, bare_error
|
|
from cherrypy.lib import httputil
|
|
from cherrypy import wsgiserver
|
|
|
|
|
|
class NativeGateway(wsgiserver.Gateway):
|
|
|
|
recursive = False
|
|
|
|
def respond(self):
|
|
req = self.req
|
|
try:
|
|
# Obtain a Request object from CherryPy
|
|
local = req.server.bind_addr
|
|
local = httputil.Host(local[0], local[1], "")
|
|
remote = req.conn.remote_addr, req.conn.remote_port
|
|
remote = httputil.Host(remote[0], remote[1], "")
|
|
|
|
scheme = req.scheme
|
|
sn = cherrypy.tree.script_name(req.uri or "/")
|
|
if sn is None:
|
|
self.send_response('404 Not Found', [], [''])
|
|
else:
|
|
app = cherrypy.tree.apps[sn]
|
|
method = req.method
|
|
path = req.path
|
|
qs = req.qs or ""
|
|
headers = req.inheaders.items()
|
|
rfile = req.rfile
|
|
prev = None
|
|
|
|
try:
|
|
redirections = []
|
|
while True:
|
|
request, response = app.get_serving(
|
|
local, remote, scheme, "HTTP/1.1")
|
|
request.multithread = True
|
|
request.multiprocess = False
|
|
request.app = app
|
|
request.prev = prev
|
|
|
|
# Run the CherryPy Request object and obtain the response
|
|
try:
|
|
request.run(method, path, qs, req.request_protocol, headers, rfile)
|
|
break
|
|
except cherrypy.InternalRedirect:
|
|
ir = sys.exc_info()[1]
|
|
app.release_serving()
|
|
prev = request
|
|
|
|
if not self.recursive:
|
|
if ir.path in redirections:
|
|
raise RuntimeError("InternalRedirector visited the "
|
|
"same URL twice: %r" % ir.path)
|
|
else:
|
|
# Add the *previous* path_info + qs to redirections.
|
|
if qs:
|
|
qs = "?" + qs
|
|
redirections.append(sn + path + qs)
|
|
|
|
# Munge environment and try again.
|
|
method = "GET"
|
|
path = ir.path
|
|
qs = ir.query_string
|
|
rfile = BytesIO()
|
|
|
|
self.send_response(
|
|
response.output_status, response.header_list,
|
|
response.body)
|
|
finally:
|
|
app.release_serving()
|
|
except:
|
|
tb = format_exc()
|
|
#print tb
|
|
cherrypy.log(tb, 'NATIVE_ADAPTER', severity=logging.ERROR)
|
|
s, h, b = bare_error()
|
|
self.send_response(s, h, b)
|
|
|
|
def send_response(self, status, headers, body):
|
|
req = self.req
|
|
|
|
# Set response status
|
|
req.status = str(status or "500 Server Error")
|
|
|
|
# Set response headers
|
|
for header, value in headers:
|
|
req.outheaders.append((header, value))
|
|
if (req.ready and not req.sent_headers):
|
|
req.sent_headers = True
|
|
req.send_headers()
|
|
|
|
# Set response body
|
|
for seg in body:
|
|
req.write(seg)
|
|
|
|
|
|
class CPHTTPServer(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_adapter
|
|
|
|
server_name = (self.server_adapter.socket_host or
|
|
self.server_adapter.socket_file or
|
|
None)
|
|
|
|
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_size or 0
|
|
self.max_request_body_size = self.server_adapter.max_request_body_size or 0
|
|
self.request_queue_size = self.server_adapter.socket_queue_size
|
|
self.timeout = self.server_adapter.socket_timeout
|
|
self.shutdown_timeout = self.server_adapter.shutdown_timeout
|
|
self.protocol = self.server_adapter.protocol_version
|
|
self.nodelay = self.server_adapter.nodelay
|
|
|
|
ssl_module = self.server_adapter.ssl_module or 'pyopenssl'
|
|
if self.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_context
|
|
elif self.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)
|
|
|
|
|