[Welcome] [TitleIndex] [WordIndex

Problem

You want to run Quixote with mod_scgi on Apache (or any other SCGI server).

Solution

In Apache 2.x httpd.conf:

   LoadModule scgi_module    modules/mod_scgi.so
   <Location /qx>
       SCGIServer localhost:3000
       SCGIHandler On
   </Location>
   RewriteEngine On
   RewriteRule   /qx   /qx/   [R=permanent]

In Apache 1.x httpd.conf:

   # @@TODO: AddModule line belongs here?
   LoadModule     scgi_module     modules/mod_scgi.so
   <Location /qx>
       SCGIServer localhost 3000
       SCGIHandler On
   </Location>
   RewriteEngine On
   RewriteRule   /qx   /qx/   [R=permanent]

In your application launch script (Quixote 2.x):

    from MyApplication import create_publisher
    from quixote.server import scgi_server
    scgi_server.run(create_publisher, port=3000, script_name="/qx")

Or launch a simple application from the command line:

    python $QUIXOTE/server/scgi_server.py \
        --factory=MyApplication.create_publisher \
        --script_name=/qx  --port=3000

Discussion

Quixote depends on the server setting the SCRIPT_NAME and PATH_INFO parameters the following way:

If <Location> is

and user requests

SCRIPT_NAME

PATH_INFO

/qx

http://example.com/qx/articles/123

/qx

/articles/123

/qx

http://example.com/qx/articles/

/qx

/articles/

/qx

http://example.com/qx/

/qx

/

/

http://example.com/articles/123

/articles/123

/

http://example.com/articles/

/articles/

/

http://example.com/

/

Apache does this automatically for most adapters (including cgi2scgi.c), but for mod_scgi it does not. So you have to tell scgi_server what the SCRIPT_NAME should have been. You must set scgi_server's script_name= or --script_name= argument to the same the same value as the <Location> URI! Otherwise you'll get an AssertionError on  assert path[:1] == '/' . If <Location> is / you must explicitly set your script_name="" or --script_name="".

The RewriteRule is necessary because if the user requests http://example.com/qx, it will match the <Location>, and Quixote won't know what to do with PATH_INFO="". The home page is "/", not "". (Most people don't realize http://example.com is an invalid URL; browsers automatically expand it to http://example.com/ .) If you forget the RewriteRule, you'll get the same AssertionError as above, but with the additional information args = ().

There may be additional problems with <Location />; see discussion on quxote-users list dated May 2005. There is also discussion about whether it's possible to turn SCGIHandler off if an outer <Location> has turned it on; e.g.,

    <Location /qx/images>
        # This may not work!!!
        SCGIHandler Off
    </Location>

Note that Apache 2's mod_scgi requires a colon between the hostname and port ("localhost:3000") but Apache 1's mod_scgi uses a space instead ("localhost 3000").

Bugs

mod_scgi and/or Apache has "Reload bug" with StaticFile and StaticDirectory content. It will display the content right the first time, but if the user presses Reload soon after, they'll get broken images or a "500 Internal Server Error". If the user keeps pressing Reload repeatedly, they'll get a correct page approximately every third time. If the images and stylesheet are static, they may get the images and stylesheet disappearing alternately. This does not affect dynamic content (not StaticFile or StaticDirectory) at all. Quixote is returning normal headers but somehow mod_scgi or Apache is misinterpreting them. Workarounds are:

cgi2scgi.c and FastCGI have a different "Reload bug". If you press Reload repeatedly, the request will hang, even if the previous request appears finished. This seems to be a race condition. This problem has been reported by only one user (Mike Orr <mso@oz.net>), so it may depend on other unknown factors.

This "Reload bug" appears to be in Apache itself. As of June 1, 2005 there is now an Apache bug report on it called ap_send_error_response ignores status returned by handler

Debian / Ubuntu and Apache2

I had problems getting by defualt Unbuntu installation to find mod_scgi.so, because Apache2 expects modules in different places then Apache1. This is how I was able to use the instructions above in my httpd.conf (which is otherwise empty): create the following file: mod_scgi.load in /etc/apache2/mods-available which has one line of text:

LoadModule scgi_module    /usr/lib/apache2/modules/mod_scgi.so

Then run a2enmod, and select mod_scgi. Then run a2enmod again and select rewrite; otherwise the rewrite instructions will choke when apache is restarted (it doesn't seem to be loaded by default). Restart apache (/etc/init.d/apache2 restart) and you should be fine. -Chris Mutel (chris@mutel.net)


CategoryCookbook CategoryScgi


2010-09-22 22:14