[Zope] Running Mailman CGI under Zope ZServer

Fred Wilson Horch fhorch@ecoaccess.org
Thu, 16 Nov 2000 20:22:02 -0500


Hello out there,

I'm looking for someone with some more Zope "Zen" to help me figure out
how to add support for legacy CGI scripts (specifically Mailman 1.1) to
Zope.

To recap, I know and understand how to get Apache to play nicely with
Zope.  What I'm trying to do is remove the need for Apache by allowing
ZServer to serve CGI scripts itself.  The motivation is to allow me to
run Mailman 1.1 on my Zope site without having to have Apache (or any
other web server) configured and running.

First, am I really the first person to try running CGI scripts from
ZServer?  I have found some hints here and there of people doing
somewhat similar things, but I haven't yet found a product for easily
adding legacy CGI scripts to a Zope site.  It seems most people run Zope
behind Apache.  Is ZServer really slow or buggy or something?

Second, is Mailman going to be integrated with Zope?  It seems like a
natural fit.  It would be nice to move away from the pipermail archiving
and use the Zope object database for archiving messages instead.

Third, thanks to code from Eric Walstad and Chris Withers (author of
PathHandler), I have hacked up an external method that sort of works. 
It attempts to add to Zope the functionality of ScriptAlias in Apache.

But I'm running into some problems with the HTTP header.  The attached
code simply ignores the HTTP header sent by the Mailman CGI script,
letting Zope do its thing.  But this becomes a problem when Mailman
wants to set cookies for authentication.

Can anyone help me figure out how to convince Zope to let the CGI script
send both the HTTP header and message body?

Thanks,
Fred

Here's my external method.  It is called by a Path Handler object.

Some notes:

1)  REQUEST['PATH_INFO'] seems to be brain dead
2)  the path_to_handle key is inserted by the PathHandler product
3)  this is written for Linux; I'm not sure how Windows handles os.popen
4)  I don't understand why sometimes this function gets called with one
argument and sometimes with two -- I always just ignore the second
argument

import os, os.path, string

def testing(self, second=None):

    if self.REQUEST.has_key('path_to_handle'):
        script = self.REQUEST['path_to_handle'][0]
        if script:
            script_path = '/home/mailman/cgi-bin/%s' % script
            if os.path.isfile(script_path):
                ENV = ''
                if len(self.REQUEST['path_to_handle']) > 1:
                    ENV = ENV + 'PATH_INFO=/%s' %
string.join(self.REQUEST['path_to_handle'][1:],'/')
                elif self.REQUEST['PATH_INFO'][-1] == '/':
                    ENV = ENV + 'PATH_INFO=/'
                ENV = ENV + ' HTTP_HOST=%s' % self.REQUEST['HTTP_HOST']
                ENV = ENV + ' SERVER_NAME=%s' %
self.REQUEST['SERVER_NAME']
                f = os.popen("/usr/bin/env %s %s" % \
                             (ENV,
                              script_path))
                header = 1
                while header:
                    if (f.readline() == '\n'):
                        header = 0
                output = f.read()  # grab the output of the CGI here
                status = f.close()
            else:
                return '%s: CGI script not found.' % script
        else:
            return 'No CGI script specified.'
    else:
        return 'No path to handle.'

    return output + '<hr>' + str(self.REQUEST.keys()) + '<hr>' +
str(self.REQUEST)