252 lines
9.3 KiB
Plaintext
252 lines
9.3 KiB
Plaintext
Web Server Configuration for Quixote
|
|
====================================
|
|
|
|
For a simple Quixote installation, there are two things you have to get
|
|
right:
|
|
|
|
* installation of the Quixote modules to Python's library (the
|
|
trick here is that the ``quixote`` package must be visible to the user
|
|
that CGI scripts run as, not necessarily to you as an interactive
|
|
command-line user)
|
|
|
|
* configuration of your web server to run Quixote driver scripts
|
|
|
|
This document is concerned with the second of these.
|
|
|
|
|
|
Which web servers?
|
|
------------------
|
|
|
|
We are only familiar with Apache, and we develop Quixote for use under
|
|
Apache. However, Quixote doesn't rely on any Apache-specific tricks;
|
|
if you can execute CGI scripts, then you can run Quixote applications
|
|
(although they'll run a lot faster with mod_scgi or FastCGI). If you
|
|
can redirect arbitrary URLs to a CGI script and preserve parts of the
|
|
URL as an add-on to the script name (with ``PATH_INFO``), then you can
|
|
run Quixote applications in the ideal manner, ie. with superfluous
|
|
implementation details hidden from the user.
|
|
|
|
|
|
Which operating systems?
|
|
------------------------
|
|
|
|
We are mainly familiar with Unix, and develop and deploy Quixote under
|
|
Linux. However, we've had several reports of people using Quixote under
|
|
Windows, more-or-less successfully. There are still a few Unix-isms in
|
|
the code, but they are being rooted out in favor of portability.
|
|
|
|
Remember that your system is only as secure as its weakest link.
|
|
Quixote can't help you write secure web applications on an inherently
|
|
insecure operating system.
|
|
|
|
|
|
Basic CGI configuration
|
|
-----------------------
|
|
|
|
Throughout this document, I'm going to assume that:
|
|
|
|
* CGI scripts live in the ``/www/cgi-bin`` directory of your web server,
|
|
and have the extension ``.cgi``
|
|
|
|
* HTTP requests for ``/cgi-bin/foo.cgi`` will result in the execution
|
|
of ``/www/cgi-bin/foo.cgi`` (for various values of ``foo``)
|
|
|
|
* if the web server is instructed to serve an executable file
|
|
``bar.cgi``, the file is treated as a CGI script
|
|
|
|
With Apache, these configuration directives will do the trick::
|
|
|
|
AddHandler cgi-script .cgi
|
|
ScriptAlias /cgi-bin/ /www/cgi-bin/
|
|
|
|
Consult the Apache documentation for other ways of configuring CGI
|
|
script execution.
|
|
|
|
For other web servers, consult your server's documentation.
|
|
|
|
|
|
Installing driver scripts
|
|
-------------------------
|
|
|
|
Given the above configuration, installing a Quixote driver script is the
|
|
same as installing any other CGI script: copy it to ``/www/cgi-bin`` (or
|
|
whatever). To install the Quixote demo's cgi driver script::
|
|
|
|
cp -p server/cgi_server.py /www/cgi-bin/demo.cgi
|
|
|
|
(The ``-p`` option ensures that ``cp`` preserves the file mode, so that
|
|
it remains executable.)
|
|
|
|
|
|
URL rewriting
|
|
-------------
|
|
|
|
With the above configuration, users need to use URLs like ::
|
|
|
|
http://www.example.com/cgi-bin/demo.cgi
|
|
|
|
to access the Quixote demo (or other Quixote applications installed in
|
|
the same way). This works, but it's ugly and unnecessarily exposes
|
|
implementation details.
|
|
|
|
In our view, it's preferable to give each Quixote application its own
|
|
chunk of URL-space -- a "virtual directory" if you like. For example,
|
|
you might want ::
|
|
|
|
http://www.example.com/qdemo
|
|
|
|
to handle the Quixote demo.
|
|
|
|
With Apache, this is quite easy, as long as mod_rewrite is compiled,
|
|
loaded, and enabled. (Building and loading Apache modules is beyond the
|
|
scope of this document; consult the Apache documentation.)
|
|
|
|
To enable the rewrite engine, use the ::
|
|
|
|
RewriteEngine on
|
|
|
|
directive. If you have virtual hosts, make sure to repeat this for each
|
|
``<VirtualHost>`` section of your config file.
|
|
|
|
The rewrite rule to use in this case is ::
|
|
|
|
RewriteRule ^/qdemo(/.*) /www/cgi-bin/demo.cgi$1 [last]
|
|
|
|
This is *not* a redirect; this is all handled with one HTTP
|
|
request/response cycle, and the user never sees ``/cgi-bin/demo.cgi`` in
|
|
a URL.
|
|
|
|
Note that requests for ``/qdemo/`` and ``/qdemo`` are *not* the same; in
|
|
particular, with the above rewrite rule, the former will succeed and the
|
|
latter will not. (Look at the regex again if you don't believe me:
|
|
``/qdemo`` doesn't match the regex, so ``demo.cgi`` is never invoked.)
|
|
|
|
The solution for ``/qdemo`` is the same as if it corresponded to a
|
|
directory in your document tree: redirect it to ``/qdemo/``. Apache
|
|
(and, presumably, other web servers) does this automatically for "real"
|
|
directories; however, ``/qdemo/`` is just a directory-like chunk of
|
|
URL-space, so either you or Quixote have to take care of the redirect.
|
|
|
|
It's almost certainly faster for you to take care of it in the web
|
|
server's configuration. With Apache, simply insert this directive
|
|
*before* the above rewrite rule::
|
|
|
|
RewriteRule ^/qdemo$ /qdemo/ [redirect=permanent]
|
|
|
|
If, for some reason, you are unwilling or unable to instruct your web
|
|
server to perform this redirection, Quixote will do it for you.
|
|
However, you have to make sure that the ``/qdemo`` URL is handled by
|
|
Quixote. Change the rewrite rule to::
|
|
|
|
RewriteRule ^/qdemo(/.*)?$ /www/cgi-bin/demo.cgi$1 [last]
|
|
|
|
Now a request for ``/qdemo`` will be handled by Quixote, and it will
|
|
generate a redirect to ``/qdemo/``. If you're using a CGI driver
|
|
script, this will be painfully slow, but it will work.
|
|
|
|
For redirecting and rewriting URLs with other web servers, consult your
|
|
server's documentation.
|
|
|
|
|
|
Long-running processes
|
|
----------------------
|
|
|
|
For serious web applications, CGI is unacceptably slow. For a CGI-based
|
|
Quixote application, you have to start a Python interpreter, load the
|
|
Quixote modules, and load your application's modules before you can
|
|
start working. For sophisticated, database-backed applications, you'll
|
|
probably have to open a new database connection as well for every hit.
|
|
|
|
Small wonder so many high-performance alternatives to CGI exist. (The
|
|
main advantages of CGI are that it is widely supported and easy to
|
|
develop with. Even for large Quixote applications, running in CGI mode
|
|
is nice in development because you don't have to kill a long-running
|
|
driver script every time the code changes.) Quixote includes support
|
|
for mod_scgi and FastCGI.
|
|
|
|
|
|
mod_scgi configuration
|
|
----------------------
|
|
|
|
SCGI is a CGI replacement written by Neil Schemenauer, one of
|
|
Quixote's developers, and is similar to FastCGI but is designed to be
|
|
easier to implement. mod_scgi simply forwards requests to an
|
|
already-running SCGI server on a different TCP port, and doesn't try
|
|
to start or stop processes, leaving that up to the SCGI server.
|
|
|
|
The SCGI code is available from <http://python.ca/scgi/>.
|
|
|
|
The quixote.server.scgi_server module is a script that
|
|
publishes the demo quixote application via SCGI. You can use
|
|
it for your application by importing it and calling the ``run()``
|
|
function with arguments to run your application, on the port
|
|
you choose. Here is an example::
|
|
|
|
#!/usr/bin/python
|
|
from quixote.server.scgi_server import run
|
|
from quixote.publish import Publisher
|
|
from mymodule import MyRootDirectory
|
|
|
|
def create_my_publisher():
|
|
return Publisher(MyRootDirectory())
|
|
|
|
run(create_my_publisher, port=3001)
|
|
|
|
The following Apache directive will direct requests to an SCGI server
|
|
running on port 3001::
|
|
|
|
SCGIMount / 127.0.0.1:3001
|
|
|
|
|
|
SCGI through CGI
|
|
----------------
|
|
|
|
Recent releases of the scgi package include cgi2scgi.c, a small program
|
|
that offers an extremely convenient way to take advantage of SCGI using
|
|
Apache or any web server that supports CGI. To use it, compile the
|
|
cgi2scgi.c and install the compiled program as usual for your
|
|
webserver. The default SCGI port is 3000, but you can change that
|
|
by adding ``-DPORT=3001`` (for example) to your compile command.
|
|
|
|
Although this method requires a new process to be launched for each
|
|
request, the process is small and fast, so the performance is
|
|
acceptable for many applications.
|
|
|
|
|
|
FastCGI configuration
|
|
---------------------
|
|
|
|
If your web server supports FastCGI, you can significantly speed up your
|
|
Quixote applications with a simple change to your configuration. You
|
|
don't have to change your code at all (unless it makes assumptions about
|
|
how many requests are handled by each process). (See
|
|
http://www.fastcgi.com/ for more information on FastCGI.)
|
|
|
|
To use FastCGI with Apache, you'll need to download mod_fastcgi from
|
|
http://www.fastcgi.com/ and add it to your Apache installation.
|
|
|
|
Configuring a FastCGI driver script is best done after reading the fine
|
|
documentation for mod_fastcgi at
|
|
http://www.fastcgi.com/mod_fastcgi/docs/mod_fastcgi.html
|
|
|
|
However, if you just want to try it with the Quixote demo to see if it
|
|
works, add this directive to your Apache configuration::
|
|
|
|
AddHandler fastcgi-script .fcgi
|
|
|
|
and copy server/fastcgi_server.py to demo.fcgi. If you're using a URL
|
|
rewrite to map requests for (eg.) ``/qdemo`` to
|
|
``/www/cgi-bin/demo.cgi``, be sure to change the rewrite -- it should
|
|
now point to ``/www/cgi-bin/demo.fcgi``.
|
|
|
|
After the first access to ``demo.fcgi`` (or ``/qdemo/`` with the
|
|
modified rewrite rule), the demo should be noticeably faster. You
|
|
should also see a ``demo.fcgi`` process running if you do ``ps -le``
|
|
(``ps -aux`` on BSD-ish systems, or maybe ``ps aux``). (On my 800 MHz
|
|
Athlon machine, there are slight but perceptible delays navigating the
|
|
Quixote demo in CGI mode. In FastCGI mode, the delay between pages is
|
|
no longer perceptible -- navigation is instantaneous.) The larger your
|
|
application is, the more code it loads, and the more work it does at
|
|
startup, the bigger a win FastCGI will be for you (in comparison to CGI).
|
|
|