1
0
mirror of https://github.com/Tygs/0bin.git synced 2023-08-10 21:13:00 +03:00
0bin/libs/cherrypy/_cpnative_server.py

155 lines
5.9 KiB
Python
Raw Normal View History

2012-04-26 23:19:12 +04:00
"""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):
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
recursive = False
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
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], "")
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
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
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
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
2015-05-10 20:19:02 +03:00
# Run the CherryPy Request object and obtain the
# response
2012-04-26 23:19:12 +04:00
try:
2015-05-10 20:19:02 +03:00
request.run(method, path, qs,
req.request_protocol, headers, rfile)
2012-04-26 23:19:12 +04:00
break
except cherrypy.InternalRedirect:
ir = sys.exc_info()[1]
app.release_serving()
prev = request
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
if not self.recursive:
if ir.path in redirections:
2015-05-10 20:19:02 +03:00
raise RuntimeError(
"InternalRedirector visited the same "
"URL twice: %r" % ir.path)
2012-04-26 23:19:12 +04:00
else:
2015-05-10 20:19:02 +03:00
# Add the *previous* path_info + qs to
# redirections.
2012-04-26 23:19:12 +04:00
if qs:
qs = "?" + qs
redirections.append(sn + path + qs)
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
# Munge environment and try again.
method = "GET"
path = ir.path
qs = ir.query_string
rfile = BytesIO()
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
self.send_response(
response.output_status, response.header_list,
response.body)
finally:
app.release_serving()
except:
tb = format_exc()
2015-05-10 20:19:02 +03:00
# print tb
2012-04-26 23:19:12 +04:00
cherrypy.log(tb, 'NATIVE_ADAPTER', severity=logging.ERROR)
s, h, b = bare_error()
self.send_response(s, h, b)
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
def send_response(self, status, headers, body):
req = self.req
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
# Set response status
req.status = str(status or "500 Server Error")
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
# 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()
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
# Set response body
for seg in body:
req.write(seg)
class CPHTTPServer(wsgiserver.HTTPServer):
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
"""Wrapper for wsgiserver.HTTPServer.
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
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.
"""
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
def __init__(self, server_adapter=cherrypy.server):
self.server_adapter = server_adapter
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
server_name = (self.server_adapter.socket_host or
self.server_adapter.socket_file or
None)
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
wsgiserver.HTTPServer.__init__(
self, server_adapter.bind_addr, NativeGateway,
minthreads=server_adapter.thread_pool,
maxthreads=server_adapter.thread_pool_max,
server_name=server_name)
2015-05-10 20:19:02 +03:00
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)
2012-04-26 23:19:12 +04:00
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
2015-05-10 20:19:02 +03:00
2012-04-26 23:19:12 +04:00
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)