NovaBryan/EVE_Dump
Log | Files | 📦 下载最新源码 (.zip) | Refs | README

_cpmodpy.py (7671B)


      1 #Embedded file name: C:\BuildAgent\work\20d73f1b24eed06e\eve\release\V24.01\carbon\common\lib\cherrypy\_cpmodpy.py
      2 import logging
      3 import sys
      4 import cherrypy
      5 from cherrypy._cpcompat import BytesIO, copyitems, ntob
      6 from cherrypy._cperror import format_exc, bare_error
      7 from cherrypy.lib import httputil
      8 
      9 def setup(req):
     10     from mod_python import apache
     11     options = req.get_options()
     12     if 'cherrypy.setup' in options:
     13         for function in options['cherrypy.setup'].split():
     14             atoms = function.split('::', 1)
     15             if len(atoms) == 1:
     16                 mod = __import__(atoms[0], globals(), locals())
     17             else:
     18                 modname, fname = atoms
     19                 mod = __import__(modname, globals(), locals(), [fname])
     20                 func = getattr(mod, fname)
     21                 func()
     22 
     23     cherrypy.config.update({'log.screen': False,
     24      'tools.ignore_headers.on': True,
     25      'tools.ignore_headers.headers': ['Range']})
     26     engine = cherrypy.engine
     27     if hasattr(engine, 'signal_handler'):
     28         engine.signal_handler.unsubscribe()
     29     if hasattr(engine, 'console_control_handler'):
     30         engine.console_control_handler.unsubscribe()
     31     engine.autoreload.unsubscribe()
     32     cherrypy.server.unsubscribe()
     33 
     34     def _log(msg, level):
     35         newlevel = apache.APLOG_ERR
     36         if logging.DEBUG >= level:
     37             newlevel = apache.APLOG_DEBUG
     38         elif logging.INFO >= level:
     39             newlevel = apache.APLOG_INFO
     40         elif logging.WARNING >= level:
     41             newlevel = apache.APLOG_WARNING
     42         apache.log_error(msg, newlevel, req.server)
     43 
     44     engine.subscribe('log', _log)
     45     engine.start()
     46 
     47     def cherrypy_cleanup(data):
     48         engine.exit()
     49 
     50     try:
     51         apache.register_cleanup(cherrypy_cleanup)
     52     except AttributeError:
     53         req.server.register_cleanup(req, cherrypy_cleanup)
     54 
     55 
     56 class _ReadOnlyRequest:
     57     expose = ('read', 'readline', 'readlines')
     58 
     59     def __init__(self, req):
     60         for method in self.expose:
     61             self.__dict__[method] = getattr(req, method)
     62 
     63 
     64 recursive = False
     65 _isSetUp = False
     66 
     67 def handler(req):
     68     global _isSetUp
     69     from mod_python import apache
     70     try:
     71         if not _isSetUp:
     72             setup(req)
     73             _isSetUp = True
     74         local = req.connection.local_addr
     75         local = httputil.Host(local[0], local[1], req.connection.local_host or '')
     76         remote = req.connection.remote_addr
     77         remote = httputil.Host(remote[0], remote[1], req.connection.remote_host or '')
     78         scheme = req.parsed_uri[0] or 'http'
     79         req.get_basic_auth_pw()
     80         try:
     81             q = apache.mpm_query
     82             threaded = q(apache.AP_MPMQ_IS_THREADED)
     83             forked = q(apache.AP_MPMQ_IS_FORKED)
     84         except AttributeError:
     85             bad_value = "You must provide a PythonOption '%s', either 'on' or 'off', when running a version of mod_python < 3.1"
     86             threaded = options.get('multithread', '').lower()
     87             if threaded == 'on':
     88                 threaded = True
     89             elif threaded == 'off':
     90                 threaded = False
     91             else:
     92                 raise ValueError(bad_value % 'multithread')
     93             forked = options.get('multiprocess', '').lower()
     94             if forked == 'on':
     95                 forked = True
     96             elif forked == 'off':
     97                 forked = False
     98             else:
     99                 raise ValueError(bad_value % 'multiprocess')
    100 
    101         sn = cherrypy.tree.script_name(req.uri or '/')
    102         if sn is None:
    103             send_response(req, '404 Not Found', [], '')
    104         else:
    105             app = cherrypy.tree.apps[sn]
    106             method = req.method
    107             path = req.uri
    108             qs = req.args or ''
    109             reqproto = req.protocol
    110             headers = copyitems(req.headers_in)
    111             rfile = _ReadOnlyRequest(req)
    112             prev = None
    113             try:
    114                 redirections = []
    115                 while True:
    116                     request, response = app.get_serving(local, remote, scheme, 'HTTP/1.1')
    117                     request.login = req.user
    118                     request.multithread = bool(threaded)
    119                     request.multiprocess = bool(forked)
    120                     request.app = app
    121                     request.prev = prev
    122                     try:
    123                         request.run(method, path, qs, reqproto, headers, rfile)
    124                         break
    125                     except cherrypy.InternalRedirect:
    126                         ir = sys.exc_info()[1]
    127                         app.release_serving()
    128                         prev = request
    129                         if not recursive:
    130                             if ir.path in redirections:
    131                                 raise RuntimeError('InternalRedirector visited the same URL twice: %r' % ir.path)
    132                             else:
    133                                 if qs:
    134                                     qs = '?' + qs
    135                                 redirections.append(sn + path + qs)
    136                         method = 'GET'
    137                         path = ir.path
    138                         qs = ir.query_string
    139                         rfile = BytesIO()
    140 
    141                 send_response(req, response.status, response.header_list, response.body, response.stream)
    142             finally:
    143                 app.release_serving()
    144 
    145     except:
    146         tb = format_exc()
    147         cherrypy.log(tb, 'MOD_PYTHON', severity=logging.ERROR)
    148         s, h, b = bare_error()
    149         send_response(req, s, h, b)
    150 
    151     return apache.OK
    152 
    153 
    154 def send_response(req, status, headers, body, stream = False):
    155     req.status = int(status[:3])
    156     req.content_type = 'text/plain'
    157     for header, value in headers:
    158         if header.lower() == 'content-type':
    159             req.content_type = value
    160             continue
    161         req.headers_out.add(header, value)
    162 
    163     if stream:
    164         req.flush()
    165     if isinstance(body, basestring):
    166         req.write(body)
    167     else:
    168         for seg in body:
    169             req.write(seg)
    170 
    171 
    172 import os
    173 import re
    174 
    175 def read_process(cmd, args = ''):
    176     fullcmd = '%s %s' % (cmd, args)
    177     pipein, pipeout = os.popen4(fullcmd)
    178     try:
    179         firstline = pipeout.readline()
    180         if re.search(ntob('(not recognized|No such file|not found)'), firstline, re.IGNORECASE):
    181             raise IOError('%s must be on your system path.' % cmd)
    182         output = firstline + pipeout.read()
    183     finally:
    184         pipeout.close()
    185 
    186     return output
    187 
    188 
    189 class ModPythonServer(object):
    190     template = '\n# Apache2 server configuration file for running CherryPy with mod_python.\n\nDocumentRoot "/"\nListen %(port)s\nLoadModule python_module modules/mod_python.so\n\n<Location %(loc)s>\n    SetHandler python-program\n    PythonHandler %(handler)s\n    PythonDebug On\n%(opts)s\n</Location>\n'
    191 
    192     def __init__(self, loc = '/', port = 80, opts = None, apache_path = 'apache', handler = 'cherrypy._cpmodpy::handler'):
    193         self.loc = loc
    194         self.port = port
    195         self.opts = opts
    196         self.apache_path = apache_path
    197         self.handler = handler
    198 
    199     def start(self):
    200         opts = ''.join([ '    PythonOption %s %s\n' % (k, v) for k, v in self.opts ])
    201         conf_data = self.template % {'port': self.port,
    202          'loc': self.loc,
    203          'opts': opts,
    204          'handler': self.handler}
    205         mpconf = os.path.join(os.path.dirname(__file__), 'cpmodpy.conf')
    206         f = open(mpconf, 'wb')
    207         try:
    208             f.write(conf_data)
    209         finally:
    210             f.close()
    211 
    212         response = read_process(self.apache_path, '-k start -f %s' % mpconf)
    213         self.ready = True
    214         return response
    215 
    216     def stop(self):
    217         os.popen('apache -k stop')
    218         self.ready = False