Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

root/branches/cp3-wsgi-remix/_cpmodpy.py

Revision 1243 (checked in by fumanchu, 2 years ago)

Lots of mixedCase to lower_with_underscores.

  • Property svn:eol-style set to native
Line 
1 """Native adapter for serving CherryPy via mod_python"""
2
3 from mod_python import apache
4 import cherrypy
5 from cherrypy._cperror import format_exc, bare_error
6 from cherrypy.lib import http
7
8
9 def setup(req):
10     # Run any setup function defined by a "PythonOption cherrypy.setup" directive.
11     options = req.get_options()
12     if 'cherrypy.setup' in options:
13         modname, fname = options['cherrypy.setup'].split('::')
14         mod = __import__(modname, globals(), locals(), [fname])
15         func = getattr(mod, fname)
16         func()
17    
18     cherrypy.config.update({'global' : {'log_to_screen' : False}})
19    
20     if cherrypy.engine.state == cherrypy._cpengine.STOPPED:
21         cherrypy.engine.start(blocking=False)
22     elif cherrypy.engine.state == cherrypy._cpengine.STARTING:
23         cherrypy.engine.wait()
24    
25     def cherrypy_cleanup(data):
26         cherrypy.engine.stop()
27     try:
28         # apache.register_cleanup wasn't available until 3.1.4.
29         apache.register_cleanup(cherrypy_cleanup)
30     except AttributeError:
31         req.server.register_cleanup(req, cherrypy_cleanup)
32
33
34 class _ReadOnlyRequest:
35     expose = ('read', 'readline', 'readlines')
36     def __init__(self, req):
37         for method in self.expose:
38             self.__dict__[method] = getattr(req, method)
39
40
41 _isSetUp = False
42 def handler(req):
43     try:
44         global _isSetUp
45         if not _isSetUp:
46             setup(req)
47             _isSetUp = True
48        
49         # Obtain a Request object from CherryPy
50         local = req.connection.local_addr
51         local = http.Host(local[0], local[1], req.connection.local_host or "")
52         remote = req.connection.remote_addr
53         remote = http.Host(remote[0], remote[1], req.connection.remote_host or "")
54        
55         scheme = req.parsed_uri[0] or 'http'
56         request = cherrypy.engine.request(local, remote, scheme)
57         req.get_basic_auth_pw()
58         request.login = req.user
59        
60         try:
61             # apache.mpm_query only became available in mod_python 3.1
62             q = apache.mpm_query
63             threaded = q(apache.AP_MPMQ_IS_THREADED)
64             forked = q(apache.AP_MPMQ_IS_FORKED)
65         except AttributeError:
66             bad_value = ("You must provide a PythonOption '%s', "
67                          "either 'on' or 'off', when running a version "
68                          "of mod_python < 3.1")
69            
70             threaded = options.get('multithread', '').lower()
71             if threaded == 'on':
72                 threaded = True
73             elif threaded == 'off':
74                 threaded = False
75             else:
76                 raise ValueError(bad_value % "multithread")
77            
78             forked = options.get('multiprocess', '').lower()
79             if forked == 'on':
80                 forked = True
81             elif forked == 'off':
82                 forked = False
83             else:
84                 raise ValueError(bad_value % "multiprocess")
85         request.multithread = bool(threaded)
86         request.multiprocess = bool(forked)
87        
88         # Run the CherryPy Request object and obtain the response
89         headers = req.headers_in.items()
90         rfile = _ReadOnlyRequest(req)
91         response = request.run(req.method, req.uri, req.args or "",
92                                req.protocol, headers, rfile)
93        
94         send_response(req, response.status, response.header_list, response.body)
95         request.close()
96     except:
97         tb = format_exc()
98         cherrypy.log(tb)
99         s, h, b = bare_error()
100         send_response(req, s, h, b)
101     return apache.OK
102
103 def send_response(req, status, headers, body):
104     # Set response status
105     req.status = int(status[:3])
106    
107     # Set response headers
108     req.content_type = "text/plain"
109     for header, value in headers:
110         if header.lower() == 'content-type':
111             req.content_type = value
112             continue
113         req.headers_out.add(header, value)
114    
115     # Set response body
116     if isinstance(body, basestring):
117         req.write(body)
118     else:
119         for seg in body:
120             req.write(seg)
121
Note: See TracBrowser for help on using the browser.

Hosted by WebFaction

Log in as guest/cpguest to create tickets