"Fossies" - the Fresh Open Source Software Archive

Member "roundup-2.0.0/roundup/cgi/apache.py" (29 Feb 2020, 5332 Bytes) of package /linux/www/roundup-2.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "apache.py": 1.6.1_vs_2.0.0.

    1 # mod_python interface for Roundup Issue Tracker
    2 #
    3 # This module is free software, you may redistribute it
    4 # and/or modify under the same terms as Python.
    5 #
    6 # This module provides Roundup Web User Interface
    7 # using mod_python Apache module.  Initially written
    8 # with python 2.3.3, mod_python 3.1.3, roundup 0.7.0.
    9 #
   10 # This module operates with only one tracker
   11 # and must be placed in the tracker directory.
   12 #
   13 # mod_python is deprecated and not well tested with release 2.0 of
   14 # roundup. mod_wsgi is the preferred interface. It may not work
   15 # with python3.
   16 
   17 # The patch from https://issues.roundup-tracker.org/issue2550821
   18 # is included. Look for this url below. It is not tested, but
   19 # we assume it's safe and syntax it seems ok.
   20 
   21 import cgi
   22 import os
   23 import threading
   24 
   25 from mod_python import apache
   26 
   27 import roundup.instance
   28 from roundup.cgi import TranslationService
   29 
   30 
   31 class Headers(dict):
   32 
   33     """HTTP headers wrapper"""
   34 
   35     def __init__(self, headers):
   36         """Initialize with `apache.table`"""
   37         super(Headers, self).__init__(headers)
   38         self.getheader = self.get
   39 
   40 
   41 class Request(object):
   42 
   43     """`apache.Request` object wrapper providing roundup client interface"""
   44 
   45     def __init__(self, request):
   46         """Initialize with `apache.Request` object"""
   47         self._req = request
   48         # .headers.getheader()
   49         self.headers = Headers(request.headers_in)
   50         # .wfile.write()
   51         self.wfile = self._req
   52 
   53     def start_response(self, headers, response):
   54         self.send_response(response)
   55         for key, value in headers:
   56             self.send_header(key, value)
   57         self.end_headers()
   58 
   59     def send_response(self, response_code):
   60         """Set HTTP response code"""
   61         self._req.status = response_code
   62 
   63     def send_header(self, name, value):
   64         """Set output header"""
   65         # value may be an instance of roundup.cgi.exceptions.HTTPException
   66         value = str(value)
   67         # XXX default content_type is "text/plain",
   68         #   and ain't overrided by "Content-Type" header
   69         if name == "Content-Type":
   70             self._req.content_type = value
   71         else:
   72             self._req.headers_out.add(name, value)
   73 
   74     def end_headers(self):
   75         """NOOP. There aint no such thing as 'end_headers' in mod_python"""
   76         pass
   77 
   78     def sendfile(self, filename, offset=0, len=-1):
   79         """Send 'filename' to the user."""
   80 
   81         return self._req.sendfile(filename, offset, len)
   82 
   83 
   84 __tracker_cache = {}
   85 """A cache of optimized tracker instances.
   86 
   87 The keys are strings giving the directories containing the trackers.
   88 The values are tracker instances."""
   89 
   90 __tracker_cache_lock = threading.Lock()
   91 """A lock used to guard access to the cache."""
   92 
   93 
   94 def handler(req):
   95     """HTTP request handler"""
   96     _options = req.get_options()
   97     _home = _options.get("TrackerHome")
   98     _lang = _options.get("TrackerLanguage")
   99     _timing = _options.get("TrackerTiming", "no")
  100     if _timing.lower() in ("no", "false"):
  101         _timing = ""
  102     _debug = _options.get("TrackerDebug", "no")
  103     _debug = _debug.lower() not in ("no", "false")
  104 
  105     # We do not need to take a lock here (the fast path) because reads
  106     # from dictionaries are atomic.
  107     if not _debug and _home in __tracker_cache:
  108         _tracker = __tracker_cache[_home]
  109     else:
  110         if not (_home and os.path.isdir(_home)):
  111             apache.log_error(
  112                 "PythonOption TrackerHome missing or invalid for %(uri)s"
  113                 % {'uri': req.uri})
  114             return apache.HTTP_INTERNAL_SERVER_ERROR
  115         if _debug:
  116             _tracker = roundup.instance.open(_home, optimize=0)
  117         else:
  118             __tracker_cache_lock.acquire()
  119             try:
  120                 # The tracker may have been added while we were acquiring
  121                 # the lock.
  122                 if _home in __tracker_cache:
  123                     _tracker = __tracker_cache[_home]
  124                 else:
  125                     _tracker = roundup.instance.open(_home, optimize=1)
  126                     __tracker_cache[_home] = _tracker
  127             finally:
  128                 __tracker_cache_lock.release()
  129     # create environment
  130     # Note: cookies are read from HTTP variables, so we need all HTTP vars
  131 
  132     # https://issues.roundup-tracker.org/issue2550821
  133     # Release 3.4 of mod_python uses add_cgi_vars() and depricates
  134     # add_common_vars. So try to use the add_cgi_vars and if it fails
  135     # with AttributeError because we are running an older mod_apache without
  136     # that function, fallback to add_common_vars.
  137     try:
  138         req.add_cgi_vars()
  139     except AttributeError:
  140         req.add_common_vars()
  141 
  142     _env = dict(req.subprocess_env)
  143     # XXX classname must be the first item in PATH_INFO.  roundup.cgi does:
  144     #       path = os.environ.get('PATH_INFO', '/').split('/')
  145     #       os.environ['PATH_INFO'] = '/'.join(path[2:])
  146     #   we just remove the first character ('/')
  147     _env["PATH_INFO"] = req.path_info[1:]
  148     if _timing:
  149         _env["CGI_SHOW_TIMING"] = _timing
  150     _form = cgi.FieldStorage(req, environ=_env)
  151     _client = _tracker.Client(_tracker, Request(req), _env, _form,
  152         translator=TranslationService.get_translation(_lang,
  153                                                       tracker_home=_home))
  154     _client.main()
  155     return apache.OK
  156 
  157 # vim: set et sts=4 sw=4 :