summaryrefslogtreecommitdiffstats
path: root/Mac/Tools/CGI/PythonCGISlave.py
diff options
context:
space:
mode:
Diffstat (limited to 'Mac/Tools/CGI/PythonCGISlave.py')
-rw-r--r--Mac/Tools/CGI/PythonCGISlave.py244
1 files changed, 0 insertions, 244 deletions
diff --git a/Mac/Tools/CGI/PythonCGISlave.py b/Mac/Tools/CGI/PythonCGISlave.py
deleted file mode 100644
index f14a582..0000000
--- a/Mac/Tools/CGI/PythonCGISlave.py
+++ /dev/null
@@ -1,244 +0,0 @@
-"""PythonCGISlave.py
-
-This program can be used in two ways:
-- As a Python CGI script server for web servers supporting "Actions", like WebStar.
-- As a wrapper for a single Python CGI script, for any "compliant" Mac web server.
-
-See CGI_README.txt for more details.
-"""
-
-#
-# Written by Just van Rossum, but partly stolen from example code by Jack.
-#
-
-
-LONG_RUNNING = 1 # If true, don't quit after each request.
-
-
-import MacOS
-MacOS.SchedParams(0, 0)
-from MiniAEFrame import AEServer, MiniApplication
-
-import os
-import string
-import cStringIO
-import sys
-import traceback
-import mimetools
-
-__version__ = '3.2'
-
-
-slave_dir = os.getcwd()
-
-
-# log file for errors
-sys.stderr = open(sys.argv[0] + ".errors", "a+")
-
-def convertFSSpec(fss):
- return fss.as_pathname()
-
-
-# AE -> os.environ mappings
-ae2environ = {
- 'kfor': 'QUERY_STRING',
- 'Kcip': 'REMOTE_ADDR',
- 'svnm': 'SERVER_NAME',
- 'svpt': 'SERVER_PORT',
- 'addr': 'REMOTE_HOST',
- 'scnm': 'SCRIPT_NAME',
- 'meth': 'REQUEST_METHOD',
- 'ctyp': 'CONTENT_TYPE',
-}
-
-
-ERROR_MESSAGE = """\
-Content-type: text/html
-
-<html>
-<head>
-<title>Error response</title>
-</head>
-<body>
-<h1>Error response</h1>
-<p>Error code %d.
-<p>Message: %s.
-</body>
-</html>
-"""
-
-
-def get_cgi_code():
- # If we're a CGI wrapper, the CGI code resides in a PYC resource.
- from Carbon import Res
- import marshal
- try:
- code = Res.GetNamedResource('PYC ', "CGI_MAIN")
- except Res.Error:
- return None
- else:
- return marshal.loads(code.data[8:])
-
-
-
-class PythonCGISlave(AEServer, MiniApplication):
-
- def __init__(self):
- self.crumblezone = 100000 * "\0"
- MiniApplication.__init__(self)
- AEServer.__init__(self)
- self.installaehandler('aevt', 'oapp', self.open_app)
- self.installaehandler('aevt', 'quit', self.quit)
- self.installaehandler('WWW\275', 'sdoc', self.cgihandler)
-
- self.code = get_cgi_code()
- self.long_running = LONG_RUNNING
-
- if self.code is None:
- print "%s version %s, ready to serve." % (self.__class__.__name__, __version__)
- else:
- print "%s, ready to serve." % os.path.basename(sys.argv[0])
-
- try:
- self.mainloop()
- except:
- self.crumblezone = None
- sys.stderr.write("- " * 30 + '\n')
- self.message("Unexpected exception")
- self.dump_environ()
- sys.stderr.write("%s: %s\n" % sys.exc_info()[:2])
-
- def getabouttext(self):
- if self.code is None:
- return "PythonCGISlave %s, written by Just van Rossum." % __version__
- else:
- return "Python CGI script, wrapped by BuildCGIApplet and " \
- "PythonCGISlave, version %s." % __version__
-
- def getaboutmenutext(self):
- return "About %s\311" % os.path.basename(sys.argv[0])
-
- def message(self, msg):
- import time
- sys.stderr.write("%s (%s)\n" % (msg, time.asctime(time.localtime(time.time()))))
-
- def dump_environ(self):
- sys.stderr.write("os.environ = {\n")
- keys = os.environ.keys()
- keys.sort()
- for key in keys:
- sys.stderr.write(" %s: %s,\n" % (repr(key), repr(os.environ[key])))
- sys.stderr.write("}\n")
-
- def quit(self, **args):
- self.quitting = 1
-
- def open_app(self, **args):
- pass
-
- def cgihandler(self, pathargs, **args):
- # We emulate the unix way of doing CGI: fill os.environ with stuff.
- environ = os.environ
-
- # First, find the document root. If we don't get a DIRE parameter,
- # we take the directory of this program, which may be wrong if
- # it doesn't live the actual http document root folder.
- if args.has_key('DIRE'):
- http_root = args['DIRE'].as_pathname()
- del args['DIRE']
- else:
- http_root = slave_dir
- environ['DOCUMENT_ROOT'] = http_root
-
- if self.code is None:
- # create a Mac pathname to the Python CGI script or applet
- script = string.replace(args['scnm'], '/', ':')
- script_path = os.path.join(http_root, script)
- else:
- script_path = sys.argv[0]
-
- if not os.path.exists(script_path):
- rv = "HTTP/1.0 404 Not found\n"
- rv = rv + ERROR_MESSAGE % (404, "Not found")
- return rv
-
- # Kfrq is the complete http request.
- infile = cStringIO.StringIO(args['Kfrq'])
- firstline = infile.readline()
-
- msg = mimetools.Message(infile, 0)
-
- uri, protocol = string.split(firstline)[1:3]
- environ['REQUEST_URI'] = uri
- environ['SERVER_PROTOCOL'] = protocol
-
- # Make all http headers available as HTTP_* fields.
- for key in msg.keys():
- environ['HTTP_' + string.upper(string.replace(key, "-", "_"))] = msg[key]
-
- # Translate the AE parameters we know of to the appropriate os.environ
- # entries. Make the ones we don't know available as AE_* fields.
- items = args.items()
- items.sort()
- for key, value in items:
- if key[0] == "_":
- continue
- if ae2environ.has_key(key):
- envkey = ae2environ[key]
- environ[envkey] = value
- else:
- environ['AE_' + string.upper(key)] = str(value)
-
- # Redirect stdout and stdin.
- saveout = sys.stdout
- savein = sys.stdin
- out = sys.stdout = cStringIO.StringIO()
- postdata = args.get('post', "")
- if postdata:
- environ['CONTENT_LENGTH'] = str(len(postdata))
- sys.stdin = cStringIO.StringIO(postdata)
-
- # Set up the Python environment
- script_dir = os.path.dirname(script_path)
- os.chdir(script_dir)
- sys.path.insert(0, script_dir)
- sys.argv[:] = [script_path]
- namespace = {"__name__": "__main__"}
- rv = "HTTP/1.0 200 OK\n"
-
- try:
- if self.code is None:
- # we're a Python script server
- execfile(script_path, namespace)
- else:
- # we're a CGI wrapper, self.code is the CGI code
- exec self.code in namespace
- except SystemExit:
- # We're not exiting dammit! ;-)
- pass
- except:
- self.crumblezone = None
- sys.stderr.write("- " * 30 + '\n')
- self.message("CGI exception")
- self.dump_environ()
- traceback.print_exc()
- sys.stderr.flush()
- self.quitting = 1
- # XXX we should return an error AE, but I don't know how to :-(
- rv = "HTTP/1.0 500 Internal error\n"
-
- # clean up
- namespace.clear()
- environ.clear()
- sys.path.remove(script_dir)
- sys.stdout = saveout
- sys.stdin = savein
-
- if not self.long_running:
- # quit after each request
- self.quitting = 1
-
- return rv + out.getvalue()
-
-
-PythonCGISlave()