apache2 FastCGI comm with dynamic server aborted first read idle timeout

Hibou57 picture Hibou57 · Mar 22, 2013 · Viewed 8.9k times · Source

Summary: Unable to run any of the most simple “Hello World” FastCGI script, any request always terminating into a time out. Seems there is no communication at all between the server and the FastCGI scripts (using dynamic FastCGI scripts).

The environment

  • Ubuntu Precise (12.04)
  • Package apache2.2-bin
  • Package apache2-mpm-prefork
  • Package libapache2-mod-fastcgi
  • Package libfcgi-perl
  • Package python-flup
  • Multiple sites configured as virtual hosts on 127.0.0.1
  • There exists a /var/lib/apache2/fastcgi directory, owned by www-data, readable by all (owner, group and others)
  • There exists a /var/lib/apache2/fastcgi/dynamic directory, owned by www-data, which is restricted to the owner (readable, writable and accessible by www-data only)
  • There exists an inode/socket file in the /var/lib/apache2/fastcgi/ directory

The FastCGI relevant configurations:

The directory /etc/apache2/mods-enabled/ holds a reference to fastcgi.conf and fastcgi.load (mod_fastcgi is enabled).

The file fastcgi.conf contains the following (left untouched, I did not edit it):

<IfModule mod_fastcgi.c>
  AddHandler fastcgi-script .fcgi
  #FastCgiWrapper /usr/lib/apache2/suexec
  FastCgiIpcDir /var/lib/apache2/fastcgi
</IfModule>

The relevant configuration file in /etc/apache2/sites-enabled/ contains the following (there is nothing more anywhere else about FastCGI specific configuration):

<DirectoryMatch /fcgi-bin>
   Options +ExecCGI
   <FilesMatch "^[^\.]+$">
      SetHandler fastcgi-script
   </FilesMatch>
</DirectoryMatch>

The test materials on the test virtual host:

There exist a fcgi-bin/test-perl.fcgi whose content is (the file is executable by all, and readable by owner and group):

#!/usr/bin/perl

use CGI::Fast qw(:standard);
    $COUNTER = 0;
    while (new CGI::Fast) {
    print header;
    print start_html("Fast CGI Rocks");
    print
        h1("Fast CGI Rocks"),
        "Invocation number ",b($COUNTER++),
            " PID ",b($$),".",
        hr;
        print end_html;
    }

There exist a fcgi-bin/test-python.fcgi whose content is (the file is executable by all, and readable by owner and group):

#!/usr/bin/python

def myapp(environ, start_response):
    start_response('200 OK', [('Content-Type', 'text/plain')])
    return ['Hello World!\n']

try:
    from flup.server.fcgi import WSGIServer
    WSGIServer(myapp).run()
except:
    import sys, traceback
    traceback.print_exc(file=open("errlog.txt","a"))

The issue

Although both fcgi-bin/test-perl.fcgi and fcgi-bin/test-python.fcgi runs normally when executed from the command‑line, none seems to work when invoked, e.g. as http://test.loc/fcgi-bin/test-perl.fcgi or http://test.loc/fcgi-bin/test-python.fcgi.

Nothing at all happens, and after some delay, I get an Error 500, and Apache error logs contains multiple entries looking like:

[<date>] [error] [client <IP>] FastCGI: comm with (dynamic) server "/<…>/fcgi-bin/<script>.fcgi" aborted: (first read) idle timeout (30 sec), referer: <referrer>
[<date>] [error] [client <IP>] FastCGI: incomplete headers (0 bytes) received from server "<…>/fcgi-bin/<script>.fcgi", referer: <referrer>

I've spent hours and hours searching the web trying to understand why it does not work, and finally decided to give up and ask for some help here.

Any pointers and check list welcome. Feel free to ask for any missing details you may feel to be relevant or worth checking.

Enjoy a nice day.

-- edit --

Issue update

In my own reply to my own question, I mentioned a weird case where things were looking suddenly fine without reasons. I later discovered this was only partly fine.

In the same virtual host, so with the exact same server configuration, some scripts, which are exactly the same (and with exact same access rights), fails depending on their location.

As a remainder, here is what's in the site configuration:

<DirectoryMatch /fcgi-bin>
   Options +ExecCGI
   <FilesMatch "^[^\.]+$">
      SetHandler fastcgi-script
   </FilesMatch>
</DirectoryMatch>

With the above, only scripts in /fcgi-bin are handled as FastCGI script. But I also have some elsewhere (still for testing): one in /cgi-bin and one in / (i.e. in the public_html directory). For this purpose, .htaccess contains this entry:

Options +ExecCGI
AddHandler fastcgi-script .fcgi

So the two others FastCGI script should work the same as the one in /fcgi-bin, but they don't, and for the time, they invariably terminates with a connexion time‑out, just like the one /fcgi-bin first did.

This makes me feel something may be wrong with the mod_fastcgi module (known bug? else?). So far, this module seems to act rather randomly.

-- edit 2 --

The above in the first edit, was an error of mine: the group was wrong with the other scripts, it had to be www-data, but it was not. So is something is wrong, stick to the answer I gave, that is, try to look at the FastCgiConfig, and see if it solve anything or at least if it honours the time‑out options.

Answer

Hibou57 picture Hibou57 · Mar 22, 2013

I will answer my own question, as it seems to be working now. However, the epilogue still looks weird.

Although the default configuration should be OK, I still wanted to review the “Module mod_fastcgi” document again. As I only wanted a dynamic FastCGI, I focused on the FastCgiConfig directive only, thus on purpose not going into FastCgiServer and FastCgiExternalServer directives.

As there was no FastCgiServer at all in the default fastcgi.conf file, I started to try to set‑up my own. For a first test, I wanted to use the -appConnTimeout option, at least to request the server to not wait so much long before it returns me an Error 500.

So I just added this in the site configuration (I did not touch fastcgi.cong), in the same file where virtual hosts are configured:

FastCgiConfig -appConnTimeout 2

This was to tell the server to wait no more than 2 seconds, instead of the 30 seconds it was waiting. I tried to invoked a FastCGI script to see if at least this configuration was working. I expected to get an error in a 2 seconds delay, but instead, the script ran without error.

What's weird, is that I then tried to remove this option, to check if it was just that addition which was just missing to make FastCGI scripts working. But after I commented‑out the option, it was still working, and the same after a full reboot.

Can't tell more, that looks weird, but this is the only thing I did, I did not edit anything else. I can just suggest people who may encounter a similar issue, to just try the above.

Sorry, if I can't explain what it did exactly. I really would like to know. It just working now, but I don't know why.