Using Zope with an existing web server
--------------------------------------
While Zope comes with a web server, you may wish to use it with an
existing web server. Use Persistent CGI (PCGI) or FastCGI to allow
your existing web server to work with Zope on Unix and Windows.
Roughly, PCGI is a protocol for translating CGI requests from a web
server into Zope requests. CGI requests are traditionally one shot
events; the web server handles a request for a CGI script by
spawning a new process to handle the requests, returning the results
of the request when the process dies.
Zope is a long running process, which means that it does not start
up and die on each request like traditional CGI programs. If it
did, each request would take far too long due to the time to start
and stop an application server like Zope. Thus, PCGI is one of the
options for gatewaying from the separate CGI processes to the Zope
long running process.
FastCGI is very similar to PCGI. Where PCGI has a "wafer-thin"
external CGI program to connect Apache and Zope, FastCGI has an
Apache module. This saves the so called "fork tax" which is incurred
when Apache forks to execute the PCGI CGI program.
Using Zope in multi-threaded mode with ZServer
----------------------------------------------
ZServer is a general purpose TCP server for publishing Zope objects
over various transport protocols. For Zope to run multi-threaded,
you must run ZServer.
ZServer is based on Sam Rushing's Medusa software. The benefit of
using Medusa as the ZServer core is that it is not protocol specific
(Medusa provides libraries to program for any protocol) and it is
easily extensible. Because Medusa is written in Python, is
extremely high performance by design, and comes with an HTTP and FTP
server, we chose it for the Zope core.
It is not necessary, however, for ZServer to actually listen for
incoming HTTP requests. If you want Apache to do the actual
listening and serving, then you can use ZServer's PCGI or FastCGI
components to communicate with Apache.
PCGI
PCGI is somewhat deprecated, but still supported.
To install PCGI, please get the PCGI support package from the Zope
2.6 tarball (it no longer ships with Zope 2.7), and read the
pcgi/README file from that package.
To run ZServer with PCGI, you must configure Zope with a PCGI
server. You can do this by adding a section to the etc/zope.conf
file like this::
address /path/to/PCGI/resource/file
Note, you must have gone through the directions in 'INSTALL.txt' for
this to work.
This command will cause Zope to start with a PCGI server as well as
any other servers you specify in the zope.conf file. For PCGI to
work, the webserver and Zope must agree on a PCGI resource file.
Now the Zope long running process is started up, and the PCGI
component is loaded and ready to receive CGI requests from your
webserver.
The installation process should create a 'Zope.cgi' PCGI file. Copy
the 'Zope.cgi' file to your web server's 'cgi-bin' directory.
On Unix you can also create a symbolic link to 'Zope.cgi' from your
cgi-bin directory. For example::
ln -s /home/amos/Zope/Zope.cgi /usr/local/apache/cgi-bin/Zope
At this point you should perform any other steps you web server
requires to install and configure a CGI script.
Note: For more information on PCGI check out Jeff Bauer's "PCGI pages",
http://starship.python.net/crew/jbauer/persistcgi/.
When your Zope.cgi file is correctly configured as a CGI script with
your web server, you are ready to access Zope through the web. You
should point your browser at:
'http://youmachine.example.com:8998/cgi-bin/Zope.cgi/manage'
(Your URL maybe be different depending on how your web server is configured.)
You should be prompted to enter a username and password. Enter the
Zope "super manager" name and password.
Note: Apache requires some tricky configuration to get it to pass
the HTTP authentication header information to Zope. See the section
'Zope authentication with existing web servers'.
There is an Apache module for Zope/PCGI:
http://www.zope.org/Members/phd/mod_pcgi2/
One can easily compile and configure it. It passes the HTTP
authentication header and other environment variables. It supports
virtual hosting.
FastCGI
FastCGI is relatively easy to set up if you have installed an Apache
module before. If you haven't, don't worry, it isn't difficult. It
comes with straightforward instructions. You will need to download
the mod_fastcgi module from FastCGI.com:
http://www.fastcgi.com/
A version more recent than 2.2.2 is needed.
Extract the archive and follow the directions in its 'INSTALL' file.
Using the 'DSO' method is usually easiest.
Next, Zope must be set up to use FastCGI. You must decide whether
you want to use FastCGI via a Unix domain socket or a TCP port.
You will have to use a TCP port if you are using a Win32 box, or any
other operating system that does not provide Unix domain sockets
(sockets in the filesystem). It is also the method you must use if
Apache and Zope reside on different computers. You will need to
select a port number. This is arbitrary, but it must not already be
in use, and if you are not the super-user, it must be a sufficiently
high number. For illustrative purposes, I will use 8889.
Unix domain sockets do not open a TCP port, which may be significant
in some tight-security situation, but it requires slightly more
setup, and so it is slightly less fool-proof. You will need to
select a location and filename for the socket. Likely options are
'/tmp/zope.soc' or within Zope's 'var' directory. Make sure that
both Zope and Apache will have adequate file permissions to read and
write to the socket. For illustrative purposes, I will use
'/tmp/zope.soc'.
This can be configured by adding a fast-cgi section in your
etc/zope.conf file. The section should look like this for a TCP
port::
address localhost:8889
To use a Unix domain socket instead, specify the path of the socket
file instead of a [hostname:]port::
address /tmp/zope.soc
You can start Zope at this point by running the 'runzope' script::
$ ./bin/runzope
Next, Apache must be set up to pass FastCGI requests to Zope. This
is done with a 'FastCgiExternalServer' directive in Apache's
httpd.conf. By using 'FastCgiExternalServer' we are telling FastCGI
that we'll be launching and killing the long-running process
manually. It goes at the beginning of 'Section 2'. This directive
will look like this for a TCP port configuration::
FastCgiExternalServer /PATH/TO/apache/htdocs/zope \
-host localhost:8889 \
-pass-header Authorization
...or like this for a socket configuration::
FastCgiIpcDir /tmp
FastCgiExternalServer /PATH/TO/apache/htdocs/zope \
-socket zope.soc \
-pass-header Authorization
The FastCgiIpcDir directive is needed to tell FastCGI where to find
the socket file. By default, FastCGI will look in /tmp/fcgi. You
*cannot* specify a full path with the '-socket' option, only a
filename within the FastCgiIpcDir.
The first argument after the directive name is confusing. Apache
maps URLs to directories and files within your 'DocumentRoot'. You
must specify the name of a file within your DocumentRoot directory,
but that file need not (and probably should not) actually exist.
When Apache tries to serve that file, it will instead send the
request through FastCGI. Make sense?
Say, for instance, you want zope to be accessible from this URL:
http://myserver.org/myzope
Suppose further that you have Apache installed at /usr/local/apache.
The directive would have to look like this::
FastCgiExternalServer /usr/local/apache/htdocs/myzope \
...
...
The next argument depends on whether you are using a TCP port or a
socket. Note that the -host (port) argument requires the hostname.
In the example, it's the same host as Apache runs on, but this need
not be the case. If you are using a socket, make sure Apache has
the appropriate privileges to find it.
The last argument, '-pass-header Authorization', tells FastCGI to
pass the Authorization headers to Zope. Without this, you would not
be able to use the Zope web management interface, or anything else
that requires authorization. (Note: This feature was not in
mod_fastcgi 2.2.2)
One more item must be added to the httpd.conf. Below the
'FastCgiExternServer' directive, enter the following::
SetHandler fastcgi-script
...changing '/zope' as appropriate. Using the
'http://myserver.org/myzope' example from above, it would look like
this::
SetHandler fastcgi-script
This creates a special case for the location specified, telling
Apache to let FastCGI handle the request.
That is all that is needed. Make sure Zope is running, start or
restart Apache, and you are finished.
Using Zope in single-threaded mode with pcgi_publisher
------------------------------------------------------
The installation process should create a 'Zope.cgi' PCGI file. Copy the
'Zope.cgi' file to your web server's cgi-bin directory.
On Unix you can also create a symbolic link to 'Zope.cgi' from your cgi-bin
directory. For example::
ln -s /home/amos/Zope/Zope.cgi /usr/local/apache/cgi-bin/Zope
At this point you should perform any other steps you web server
requires to install and configure a CGI script.
Note: For more information on PCGI check out Jeff Bauer's "PCGI pages",
http://starship.python.net/crew/jbauer/persistcgi/.
When your Zope.cgi file is correctly configured as a CGI script with
your web server, you are ready to access Zope through the web. You
should point your browser at:
'http://youmachine.example.com:8998/cgi-bin/Zope.cgi/manage'
(Your URL maybe be different depending on how your web server is
configured.)
You should be prompted to enter a username and password. Enter the Zope
"super manager" name and password.
Zope authentication with existing web servers
---------------------------------------------
Zope normally performs both authentication and authorization of
users. Some web servers don't pass authentication information to
CGI scripts. If you keep getting rejected when you try to access
Zope through the web with the "super manager" user name and
password, there is a good chance that your web server is not passing
authentication information to Zope.
Getting Apache to pass authentication headers
Before attempting to use your own Apache with Zope, it is highly
recommended that you look at Zap. Zap is a preconfigured and
precompiled version of Apache for Linux that drops right into Zope
with no hassles. Even if you want to use your own Apache, or if
you use it on a different platform than Linux, it is very helpful
to have Zap's 'httpd.conf' file to guide you through configuring
Apache.
Zap can be found on the Zope website at:
http://www.zope.org/Download/Releases/Zap-1.1.0
If you are using Apache you will need to convince Apache to pass
authentication headers to Zope. The easiest way to do this with
Apache 1.3 and above is to use mod_rewrite. Here is an example of
configuration information which you would place in an Apache conf
file::
# Zope configuration maps /Zope/ to the Zope.cgi CGI script
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^/Zope(.*) /usr/local/apache/cgi-bin/Zope.cgi/$1 [e=HTTP_CGI_AUTHORIZATION:%1,t=application/x-httpd-cgi,l]
Note that the RewriteRule should be one long line, and that the last
character is the letter l, not the number 1.
For Apache servers version 1.3b4 and above, there is an alternate way
to get the server to pass through authorization headers, but you must
have the ability to recompile your Apache server binary. If you pass
the flag -DSECURITY_HOLE_PASS_AUTHORIZATION when compiling the server,
the resulting Apache binary will allow authorization headers to pass
through to CGI programs and you can avoid using the Rewrite rules
described above.
Allowing your server to handle authentication itself
Sometimes you may prefer to handle authentication outside Zope, for
example if your web server already does complex authorization, or
if it seems too difficult to convince it to pass authentication
information to Zope.
As of 1.9, Zope began supporting a mode that allowed the web
server to handle authentication. The 'REMOTE_USER' environment
variable is then matched to the identity of a user object in Zope.
The following provide step-by-step instructions for setting this
up in Apache, allowing both the Zope "super manager" defined in
the Zope 'access' file and users defined in Zope User Folders to
be authenticated via the web server.
Get Apache to authenticate /cgi-bin/Zope
Add a directive in your Apache configuration file such as::
AuthType Basic
AuthName Zope-realm
AuthUserFile /usr/local/etc/httpd/conf/ru_users
require valid-user
Then send Apache a '-1' signal to tell it to re-read its
configuration files.
*Note*: The above presumes that '/cgi-bin/Zope' has been made
executable by some other Apache directive in the configuration
file.
Ensure Apache has 'superuser'
Using Apache's tools for managing a user database, make
sure that the 'AuthUserFile' defined above has a valid user
called 'superuser'.
Get Zope to use Apache's authentication
Change Zope's access file to contain just the superuser
id followed by a colon, as in::
superuser:
Note that this can be any value, including spaces. The only
restriction is that the value must match a user defined in
Apache's user database.
N.B.: removing the password in the access file also enables
access to the monitor for any user connecting through
the localhost interface -- DISABLE THE MONITOR if using
this option on any box which allows untrusted logins.
Shut down Zope by doing::
kill `cat var/Main.pid`
from the Zope directory.
Configure Zope
At this point you are able to log in using the "superuser"
identity. If you want other people defined in the Apache user
database to have identities in Zope, you need to add them to
a User Folder (the object whose ID is acl_users). Either click on
the pre-defined acl_users in the top folder or add a User Folder
object to a subfolder.
Specific web servers
Apache
* As mentioned above, Apache does not pass authorization
information to CGI scripts by default. See above for information
on how to deal with this situation.
* There is Apache module to support PCGI (mod_pcgi2). See the
section "PCGI" above for details.
Netscape Servers
* Like Apache, Netscape does not pass HTTP Authorization
information to CGI scripts. We have a plugin at our website
that addresses this. http://www.zope.org
* Alternatively, you can allow the web server to perform the
authentication step. See above for more information.
IIS
* You must turn off Windows NT Challenge/Response
authentication. To do this, go to IIS Manager, right-click on
the server, select Service Properties, and deselect *both*
'Windows NT Challenge/Response' and, strangely, Basic
Authentication from the Password Authentication area of the
Service tabbed worksheet.
* IIS kindly throws out PATH_INFO when writing to its logs, so if
you want to log which Zope objects are actually being
accessed, you will need to investigate an ISAPI filter
* An ISAPI module to support PCGI is under development.
* IIS 4.0 throws away Zope's error messages by default. This
behavior can create quite a few problems, including
authentication problems.
Microsoft prides itself on the clear error messages that IIS 4.0
presents, when the user makes a mistake. These error messages
are implemented in the form of Custom Error handlers, that
return a file, or URL to a user when a certain error occurs.
This means, that when you forget to fill in an Id when you want
to create, say, a new SQL Method, Zope's clear error message is
replaced by IIS's totally irrelevant error message. Also, it
completely breaks authentication when the user uses IE5.0 when
trying to log into a secure area of the server. These Custom
Error handlers are enabled by default.
Luckily, the handlers can quite easily be switched off:
Open the IIS website in the Management Console, and navigate to
the folder you put the PCGI executable in. If you named your
Zope installation 'Zope', it will be called
'Zope.exe'. Double-click on that file. A property page will
appear. Select the 'Custom Errors' tab. Now, select every HTTP
Error code in the listbox that doesn't have type 'Default', and
click on the 'Set to Default' button for each one. This will
disable IIS overriding the error message returned by Zope.
Click OK, and voila, Zope is allowed to tell the world what it
thinks went wrong.