Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/cherrypy/_cpnative_server.py
diff options
context:
space:
mode:
authorSebastian Silva <sebastian@somosazucar.org>2011-07-09 00:17:44 (GMT)
committer Icarito <icarito@spock.(none)>2011-07-09 00:18:57 (GMT)
commit570a268e7562303690ef6b599ea244945a3100ce (patch)
tree1f772420739a73515671f73dfeb397870daa9fe0 /cherrypy/_cpnative_server.py
parent365ef228a2a94708024030d3993bb9f0a152a038 (diff)
Still importing WebSDK.
Need to read up on GIT.
Diffstat (limited to 'cherrypy/_cpnative_server.py')
-rwxr-xr-xcherrypy/_cpnative_server.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/cherrypy/_cpnative_server.py b/cherrypy/_cpnative_server.py
new file mode 100755
index 0000000..57f715a
--- /dev/null
+++ b/cherrypy/_cpnative_server.py
@@ -0,0 +1,149 @@
+"""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)
+
+