Fixed python_path problem.
[smonitor.git] / lib / cherrypy / _cpnative_server.py
blob57f715a9307e164272df071bbb799091e5c545d4
1 """Native adapter for serving CherryPy via its builtin server."""
3 import logging
4 import sys
6 import cherrypy
7 from cherrypy._cpcompat import BytesIO
8 from cherrypy._cperror import format_exc, bare_error
9 from cherrypy.lib import httputil
10 from cherrypy import wsgiserver
13 class NativeGateway(wsgiserver.Gateway):
15 recursive = False
17 def respond(self):
18 req = self.req
19 try:
20 # Obtain a Request object from CherryPy
21 local = req.server.bind_addr
22 local = httputil.Host(local[0], local[1], "")
23 remote = req.conn.remote_addr, req.conn.remote_port
24 remote = httputil.Host(remote[0], remote[1], "")
26 scheme = req.scheme
27 sn = cherrypy.tree.script_name(req.uri or "/")
28 if sn is None:
29 self.send_response('404 Not Found', [], [''])
30 else:
31 app = cherrypy.tree.apps[sn]
32 method = req.method
33 path = req.path
34 qs = req.qs or ""
35 headers = req.inheaders.items()
36 rfile = req.rfile
37 prev = None
39 try:
40 redirections = []
41 while True:
42 request, response = app.get_serving(
43 local, remote, scheme, "HTTP/1.1")
44 request.multithread = True
45 request.multiprocess = False
46 request.app = app
47 request.prev = prev
49 # Run the CherryPy Request object and obtain the response
50 try:
51 request.run(method, path, qs, req.request_protocol, headers, rfile)
52 break
53 except cherrypy.InternalRedirect:
54 ir = sys.exc_info()[1]
55 app.release_serving()
56 prev = request
58 if not self.recursive:
59 if ir.path in redirections:
60 raise RuntimeError("InternalRedirector visited the "
61 "same URL twice: %r" % ir.path)
62 else:
63 # Add the *previous* path_info + qs to redirections.
64 if qs:
65 qs = "?" + qs
66 redirections.append(sn + path + qs)
68 # Munge environment and try again.
69 method = "GET"
70 path = ir.path
71 qs = ir.query_string
72 rfile = BytesIO()
74 self.send_response(
75 response.output_status, response.header_list,
76 response.body)
77 finally:
78 app.release_serving()
79 except:
80 tb = format_exc()
81 #print tb
82 cherrypy.log(tb, 'NATIVE_ADAPTER', severity=logging.ERROR)
83 s, h, b = bare_error()
84 self.send_response(s, h, b)
86 def send_response(self, status, headers, body):
87 req = self.req
89 # Set response status
90 req.status = str(status or "500 Server Error")
92 # Set response headers
93 for header, value in headers:
94 req.outheaders.append((header, value))
95 if (req.ready and not req.sent_headers):
96 req.sent_headers = True
97 req.send_headers()
99 # Set response body
100 for seg in body:
101 req.write(seg)
104 class CPHTTPServer(wsgiserver.HTTPServer):
105 """Wrapper for wsgiserver.HTTPServer.
107 wsgiserver has been designed to not reference CherryPy in any way,
108 so that it can be used in other frameworks and applications.
109 Therefore, we wrap it here, so we can apply some attributes
110 from config -> cherrypy.server -> HTTPServer.
113 def __init__(self, server_adapter=cherrypy.server):
114 self.server_adapter = server_adapter
116 server_name = (self.server_adapter.socket_host or
117 self.server_adapter.socket_file or
118 None)
120 wsgiserver.HTTPServer.__init__(
121 self, server_adapter.bind_addr, NativeGateway,
122 minthreads=server_adapter.thread_pool,
123 maxthreads=server_adapter.thread_pool_max,
124 server_name=server_name)
126 self.max_request_header_size = self.server_adapter.max_request_header_size or 0
127 self.max_request_body_size = self.server_adapter.max_request_body_size or 0
128 self.request_queue_size = self.server_adapter.socket_queue_size
129 self.timeout = self.server_adapter.socket_timeout
130 self.shutdown_timeout = self.server_adapter.shutdown_timeout
131 self.protocol = self.server_adapter.protocol_version
132 self.nodelay = self.server_adapter.nodelay
134 ssl_module = self.server_adapter.ssl_module or 'pyopenssl'
135 if self.server_adapter.ssl_context:
136 adapter_class = wsgiserver.get_ssl_adapter_class(ssl_module)
137 self.ssl_adapter = adapter_class(
138 self.server_adapter.ssl_certificate,
139 self.server_adapter.ssl_private_key,
140 self.server_adapter.ssl_certificate_chain)
141 self.ssl_adapter.context = self.server_adapter.ssl_context
142 elif self.server_adapter.ssl_certificate:
143 adapter_class = wsgiserver.get_ssl_adapter_class(ssl_module)
144 self.ssl_adapter = adapter_class(
145 self.server_adapter.ssl_certificate,
146 self.server_adapter.ssl_private_key,
147 self.server_adapter.ssl_certificate_chain)