diff options
Diffstat (limited to 'Mac/Tools/CGI')
-rw-r--r-- | Mac/Tools/CGI/BuildCGIApplet.py | 76 | ||||
-rw-r--r-- | Mac/Tools/CGI/BuildCGIApplet.rsrc | bin | 581 -> 0 bytes | |||
-rw-r--r-- | Mac/Tools/CGI/CGI_README.txt | 66 | ||||
-rw-r--r-- | Mac/Tools/CGI/PythonCGISlave.py | 244 | ||||
-rw-r--r-- | Mac/Tools/CGI/PythonCGISlave.rsrc | bin | 581 -> 0 bytes | |||
-rw-r--r-- | Mac/Tools/CGI/cgi.html | 53 |
6 files changed, 0 insertions, 439 deletions
diff --git a/Mac/Tools/CGI/BuildCGIApplet.py b/Mac/Tools/CGI/BuildCGIApplet.py deleted file mode 100644 index 0ee2ce0..0000000 --- a/Mac/Tools/CGI/BuildCGIApplet.py +++ /dev/null @@ -1,76 +0,0 @@ -"""BuildCGIApplet.py -- Create a CGI applet from a Python script. - -Specilized version of BuildApplet, enabling Python CGI scripts to be -used under Mac web servers like WebStar. The __main__ program is -PythonCGISlave.py, which provides a compatibility layer, emulating -Unix-style CGI scripts. See CGI_README.txt for details. -""" - -import sys -import os -import macfs -import MacOS -from Carbon import Res -import EasyDialogs -import buildtools -import py_resource - - -def main(): - try: - buildcgiapplet() - except buildtools.BuildError, detail: - EasyDialogs.Message(detail) - - -def buildcgiapplet(): - buildtools.DEBUG=1 - - # Find the template - # (there's no point in proceeding if we can't find it) - - template = buildtools.findtemplate() - wrapper = "PythonCGISlave.py" - if not os.path.exists("PythonCGISlave.py"): - wrapper = os.path.join(sys.exec_prefix, ":Mac:Tools:CGI", wrapper) - - # Ask for source text if not specified in sys.argv[1:] - if not sys.argv[1:]: - srcfss, ok = macfs.PromptGetFile('Select a CGI script:', 'TEXT', 'APPL') - if not ok: - return - filename = srcfss.as_pathname() - dstfilename = mkcgifilename(filename) - dstfss, ok = macfs.StandardPutFile('Save application as:', - os.path.basename(dstfilename)) - if not ok: - return - dstfilename = dstfss.as_pathname() - buildone(template, wrapper, filename, dstfilename) - else: - # Loop over all files to be processed - for filename in sys.argv[1:]: - dstfilename = mkcgifilename(filename) - buildone(template, wrapper, filename, dstfilename) - - -def mkcgifilename(filename): - if filename[-3:] == '.py': - filename = filename[:-3] - filename = filename + ".cgi" - return filename - - -def buildone(template, wrapper, src, dst): - buildtools.process(template, wrapper, dst, 1) - # write source as a PYC resource into dst - ref = Res.FSpOpenResFile(dst, 2) - try: - Res.UseResFile(ref) - py_resource.frompyfile(src, "CGI_MAIN", preload=1) - finally: - Res.CloseResFile(ref) - - -if __name__ == '__main__': - main() diff --git a/Mac/Tools/CGI/BuildCGIApplet.rsrc b/Mac/Tools/CGI/BuildCGIApplet.rsrc Binary files differdeleted file mode 100644 index cc11108..0000000 --- a/Mac/Tools/CGI/BuildCGIApplet.rsrc +++ /dev/null diff --git a/Mac/Tools/CGI/CGI_README.txt b/Mac/Tools/CGI/CGI_README.txt deleted file mode 100644 index 89f559f..0000000 --- a/Mac/Tools/CGI/CGI_README.txt +++ /dev/null @@ -1,66 +0,0 @@ -Python CGI under MacOS - -This folder contains two tools that enable Python CGI scripts under -Mac based web servers, like WebStar, Quid Quo Pro, NetPresentz or -Apple's Personal Webserver. - -Both tools emulate Unix style CGI's, allowing for cross platform -CGI scripts. In short, this happens by converting an AppleEvent sent -by the web server into os.environ dictionary entries. See below for more -details. - -Both tools serve slightly different purposes: -- PythonCGISlave enables execution of Python scripts as plain *.py - text files. The web server must be configured to handle .py requests - over to PythonCGISlave. Not all web servers support that. Eg. WebStar - does, but NetPresentz does not. -- BuildCGIApplet wraps a Python CGI script in a compatibility layer, and - creates a CGI Applet which can be executed by any web server. - -The pros and cons of using PythonCGISlave are (+ is good, - is bad): - + support plain .py files, no need to wrap each script - - not supported b all servers, requires more complicated configuration -The pros and cons of using BuildCGIApplet are: - + supported by more servers - + less configuration troubles - - must wrap each script - - -Using BuildCGIApplet - -Drop your CGI script onto BuildCGIApplet. An applet called <script name>.cgi -will be created. Move it to the appropriate location in the HTTP document tree. -Make sure your web server is configured to handle .cgi applet files. Usually -it is configured correctly by default, since .cgi is a standard extension. -If your CGI applet starts up for the first time, a file <applet name>.errors -is created. If your CGI script causes an exception, debug info will be written -to that file. - - -Using PythonCGISlave - -Place the PythonCGISlave applet somewhere in the HTTP document tree. Configure -your web server so it'll pass requests for .py files to PythonCGISlave. For -Webstar, this goes roughly like this: -- in the WebStar Admin app, create a new "action", call it PYTHON, click the - "Choose" button and select our applet. Save the settings. -- go to Suffix Mappings, create a new suffix .PY, type TEXT, creator *, and - choose PYTHON in the actions popup. Save the settings. - - -How it works - -For each Python CGI request, the web server will send an AppleEvent to the -CGI applet. Most relevant CGI parameters are taken from the AppleEvent and -get stuffed into the os.environ dictionary. Then the script gets executed. -This emulates Unix-style CGI as much as possible, so CGI scripts that are -written portably should now also work under a Mac web server. - -Since the applet does not quit after each request by default, there is hardly -any startup overhead except the first time it starts up. If an exception occurs -in the CGI script, the applet will write a traceback to a file called -<applet name>.errors, and then quit. The latter seems a good idea, just in case -we leak memory. The applet will be restarted upon the next request. - - -Please direct feedback to <just@letterror.com> and/or <pythonmac-sig@python.org>. 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() diff --git a/Mac/Tools/CGI/PythonCGISlave.rsrc b/Mac/Tools/CGI/PythonCGISlave.rsrc Binary files differdeleted file mode 100644 index caf8e76..0000000 --- a/Mac/Tools/CGI/PythonCGISlave.rsrc +++ /dev/null diff --git a/Mac/Tools/CGI/cgi.html b/Mac/Tools/CGI/cgi.html deleted file mode 100644 index 3dc5dc0..0000000 --- a/Mac/Tools/CGI/cgi.html +++ /dev/null @@ -1,53 +0,0 @@ -<HTML> -<HEAD> - <META NAME="GENERATOR" CONTENT="Adobe PageMill 3.0 Mac"> - <TITLE>Creating CGI scripts with MacPython</TITLE> -</HEAD> -<BODY> - -<H3>Creating CGI scripts with MacPython</H3> -<BLOCKQUOTE> -Note: this document is work-in-progress, and not tested. -</BLOCKQUOTE> - -<P>MacPython allows you to use Python as a CGI scripting language -for your webserver. Moreover, there are some helper applications -that allow you to write your CGI scripts in the same way as for -Unix and Windows, i.e. obtaining their arguments from <TT>os.environ</TT> -and sending their results to <TT>stdout</TT>. MacPython also has -all the facilities to program CGI scripts in the Macintosh way, -through AppleEvents, but that falls outside the scope of this -document (reading the source code for the helper scripts will -give you an idea about how to do this).</P> - -<P>For the purpose of this document we will assume you are using -Apple's Personal Webserver 1.5, which comes standard with your -machine as of MacOS 9.</P> - -<P>The first step is to start the webserver, you will find it -in your control panels. Give it a folder to serve documents from, -and check that it is working by pointing your browser at it.</P> - -<P>The next step is to tell the webserver that documents with -a ".<TT>py</TT>" extension should be served through -the <TT>PythonCGISlave</TT> helper application. Open the webserver, -choose Preferences, tab Action, Add, Start on Extension, extension -".py", select application <TT>PythonCGISlave</TT> (which -lives in <TT>Python:Mac:Tools:CGI</TT>).</P> - -<P>The last step is to try it. Put the following script in <TT>Macintosh -HD:Webpages:hello.py </TT>(assuming your webserver has the default -settings for its document folder):</P> - -<BLOCKQUOTE> - <P><CODE>print "Content-type: text/plain"<BR> - print<BR> - print "Hello world!"<BR> - import time<BR> - print "Local time is", time.ctime(time.time())</CODE></P></BLOCKQUOTE> - -<P>Point your webbrowser at <A HREF="http://localhost/hello.py">http://localhost/hello.py</A><CODE> -</CODE>and check whether it works. - -</BODY> -</HTML> |