Mercurial > p > roundup > code
view frontends/roundup.cgi @ 8513:d7d91e25a1c2
chore(build): bump anchore/scan-action from 7.2.3 to 7.3.0 pull #80
| author | John Rouillard <rouilj@ieee.org> |
|---|---|
| date | Tue, 27 Jan 2026 21:41:37 -0500 |
| parents | 978285986b2c |
| children | 5fbf6451a782 |
line wrap: on
line source
#!/usr/bin/env python # # Copyright (c) 2001 Bizar Software Pty Ltd (http://www.bizarsoftware.com.au/) # This module is free software, and you may redistribute it and/or modify # under the same terms as Python, so long as this copyright message and # disclaimer are retained in their original form. # # IN NO EVENT SHALL BIZAR SOFTWARE PTY LTD BE LIABLE TO ANY PARTY FOR # DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING # OUT OF THE USE OF THIS CODE, EVEN IF THE AUTHOR HAS BEEN ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. # # BIZAR SOFTWARE PTY LTD SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, # BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS # FOR A PARTICULAR PURPOSE. THE CODE PROVIDED HEREUNDER IS ON AN "AS IS" # BASIS, AND THERE IS NO OBLIGATION WHATSOEVER TO PROVIDE MAINTENANCE, # SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. # python version check from __future__ import print_function from roundup import version_check from roundup.i18n import _ from roundup.anypy.html import html_escape from roundup.anypy.strings import s2b, StringIO import sys, time # ## Configuration # # Configuration can also be provided through the OS environment (or via # the Apache "SetEnv" configuration directive). If the variables # documented below are set, they _override_ any configuation defaults # given in this file. # TRACKER_HOMES is a list of trackers, in the form # "NAME=DIR<sep>NAME2=DIR2<sep>...", where <sep> is the directory path # separator (";" on Windows, ":" on Unix). # Make sure the NAME part doesn't include any url-unsafe characters like # spaces, as these confuse the cookie handling in browsers like IE. # ROUNDUP_LOG is the name of the logfile; if it's empty or does not exist, # logging is turned off (unless you changed the default below). # DEBUG_TO_CLIENT specifies whether debugging goes to the HTTP server (via # stderr) or to the web client (via cgitb). DEBUG_TO_CLIENT = False # This indicates where the Roundup tracker lives TRACKER_HOMES = { # 'example': '/path/to/example', } # Where to log debugging information to. Use an instance of DevNull if you # don't want to log anywhere. class DevNull: def write(self, info): pass def close(self): pass def flush(self): pass #LOG = open('/var/log/roundup.cgi.log', 'a') LOG = DevNull() # ## end configuration # # # Set up the error handler # try: import traceback from roundup.cgi import cgitb except: print("Content-Type: text/plain\n") print(_("Failed to import cgitb!\n\n")) s = StringIO() traceback.print_exc(None, s) print(s.getvalue()) # # Check environment for config items # def checkconfig(): import os global TRACKER_HOMES, LOG # see if there's an environment var. ROUNDUP_INSTANCE_HOMES is the # old name for it. if 'ROUNDUP_INSTANCE_HOMES' in os.environ: homes = os.environ.get('ROUNDUP_INSTANCE_HOMES') else: homes = os.environ.get('TRACKER_HOMES', '') if homes: TRACKER_HOMES = {} for home in homes.split(os.pathsep): try: name, dir = home.split('=', 1) except ValueError: # ignore invalid definitions continue if name and dir: TRACKER_HOMES[name] = dir logname = os.environ.get('ROUNDUP_LOG', '') if logname: LOG = open(logname, 'a') # ROUNDUP_DEBUG is checked directly in "roundup.cgi.client" # # Provide interface to CGI HTTP response handling # class RequestWrapper: '''Used to make the CGI server look like a BaseHTTPRequestHandler ''' def __init__(self, wfile): self.rfile = sys.stdin self.wfile = wfile def write(self, data): self.wfile.write(data) def send_response(self, code): self.write(s2b('Status: %s\r\n'%code)) def send_header(self, keyword, value): self.write(s2b("%s: %s\r\n" % (keyword, value))) def end_headers(self): self.write(b"\r\n") def start_response(self, headers, response): self.send_response(response) for key, value in headers: self.send_header(key, value) self.end_headers() # # Main CGI handler # def main(out, err): import os import roundup.instance path = os.environ.get('PATH_INFO', '/').split('/') request = RequestWrapper(out) request.path = os.environ.get('PATH_INFO', '/') tracker = path[1] os.environ['TRACKER_NAME'] = tracker os.environ['PATH_INFO'] = '/'.join(path[2:]) if tracker in TRACKER_HOMES: # redirect if we need a trailing '/' if len(path) == 2: request.send_response(301) # redirect if os.environ.get('HTTPS', '') == 'on': protocol = 'https' else: protocol = 'http' absolute_url = '%s://%s%s/'%(protocol, os.environ['HTTP_HOST'], os.environ.get('REQUEST_URI', '')) request.send_header('Location', absolute_url) request.end_headers() out.write(b'Moved Permanently') else: tracker_home = TRACKER_HOMES[tracker] tracker = roundup.instance.open(tracker_home) import roundup.cgi.client if hasattr(tracker, 'Client'): client = tracker.Client(tracker, request, os.environ) else: client = roundup.cgi.client.Client(tracker, request, os.environ) try: client.main() except roundup.cgi.client.Unauthorised: request.send_response(403) request.send_header('Content-Type', 'text/html') request.end_headers() out.write(b'Unauthorised') except roundup.cgi.client.NotFound: request.send_response(404) request.send_header('Content-Type', 'text/html') request.end_headers() out.write(s2b('Not found: %s'%html_escape(client.path))) else: from roundup.anypy import urllib_ request.send_response(200) request.send_header('Content-Type', 'text/html') request.end_headers() w = request.write w(s2b(_('<html><head><title>Roundup trackers index</title></head>\n'))) w(s2b(_('<body><h1>Roundup trackers index</h1><ol>\n'))) homes = sorted(TRACKER_HOMES.keys()) for tracker in homes: w(s2b(_('<li><a href="%(tracker_url)s/index">%(tracker_name)s</a>\n')%{ 'tracker_url': os.environ['SCRIPT_NAME']+'/'+ urllib_.quote(tracker), 'tracker_name': html_escape(tracker)})) w(s2b(_('</ol></body></html>'))) # # Now do the actual CGI handling # out, err = sys.stdout, sys.stderr try: # force input/output to binary (important for file up/downloads) if sys.platform == "win32": import os, msvcrt msvcrt.setmode(sys.stdin.fileno(), os.O_BINARY) msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) checkconfig() sys.stdout = sys.stderr = LOG if sys.version_info[0] > 2: out_buf = out.buffer else: out_buf = out main(out_buf, err) except SystemExit: pass except: sys.stdout, sys.stderr = out, err out.write('Content-Type: text/html\n\n') if DEBUG_TO_CLIENT: cgitb.handler() else: out.write(cgitb.breaker()) ts = time.ctime() out.write('''<p>%s: An error occurred. Please check the server log for more information.</p>'''%ts) print('EXCEPTION AT', ts, file=sys.stderr) traceback.print_exc(0, sys.stderr) sys.stdout.flush() sys.stdout, sys.stderr = out, err LOG.close() # vim: set filetype=python ts=4 sw=4 et si
