Apache Server Frequently Asked Questions

$Revision: 1.99 $ ($Date: 2010/12/10 10:13:45 $)

Please note that this document refers to a version of the product which has been deprecated, and declared "end of life", in favor of the more recent version of the server. Information obtained here is likely to be outdated and inaccurate.

The latest version of this FAQ is available on the HTTP Server Wiki, at <http://httpd.apache.org/docs/1.3/misc/FAQ.html>. This version is no longer maintained, and contains inaccurate and grossly outdated information.

The Questions

  1. Dynamic Content (CGI and SSI)
    1. How do I enable CGI execution in directories other than the ScriptAlias?
    2. What does it mean when my CGIs fail with "Premature end of script headers"?
    3. Why do I keep getting "Method Not Allowed" for form POST requests?
    4. How can I get my script's output without Apache buffering it? Why doesn't my server push work?
    5. Where can I find the "CGI specification"?
    6. Why isn't FastCGI included with Apache any more?
    7. How do I enable SSI (parsed HTML)?
    8. Why don't my parsed files get cached?
    9. How can I have my script output parsed?
    10. SSIs don't work for VirtualHosts and/or user home directories
    11. How can I use ErrorDocument and SSI to simplify customized error messages?
    12. Why is the environment variable REMOTE_USER not set?
    13. How do I allow each of my user directories to have a cgi-bin directory?

The Answers

F. Dynamic Content (CGI and SSI)

  1. How do I enable CGI execution in directories other than the ScriptAlias?

    Apache recognizes all files in a directory named as a ScriptAlias as being eligible for execution rather than processing as normal documents. This applies regardless of the file name, so scripts in a ScriptAlias directory don't need to be named "*.cgi" or "*.pl" or whatever. In other words, all files in a ScriptAlias directory are scripts, as far as Apache is concerned.

    To persuade Apache to execute scripts in other locations, such as in directories where normal documents may also live, you must tell it how to recognize them - and also that it's okay to execute them. For this, you need to use something like the AddHandler directive.

    1. In an appropriate section of your server configuration files, add a line such as
      AddHandler cgi-script .cgi

      The server will then recognize that all files in that location (and its logical descendants) that end in ".cgi" are script files, not documents.

    2. Make sure that the directory location is covered by an Options declaration that includes the ExecCGI option.

    In some situations, you might not want to actually allow all files named "*.cgi" to be executable. Perhaps all you want is to enable a particular file in a normal directory to be executable. This can be alternatively accomplished via mod_rewrite and the following steps:

    1. Locally add to the corresponding .htaccess file a ruleset similar to this one:
      RewriteEngine on
      RewriteBase /~foo/bar/
      RewriteRule ^quux\.cgi$ - [T=application/x-httpd-cgi]
    2. Make sure that the directory location is covered by an Options declaration that includes the ExecCGI and FollowSymLinks option.

  2. What does it mean when my CGIs fail with "Premature end of script headers"?

    It means just what it says: the server was expecting a complete set of HTTP headers (one or more followed by a blank line), and didn't get them.

    The most common cause of this problem is the script dying before sending the complete set of headers, or possibly any at all, to the server. To see if this is the case, try running the script standalone from an interactive session, rather than as a script under the server. If you get error messages, this is almost certainly the cause of the "premature end of script headers" message. Even if the CGI runs fine from the command line, remember that the environment and permissions may be different when running under the web server. The CGI can only access resources allowed for the User and Group specified in your Apache configuration. In addition, the environment will not be the same as the one provided on the command line, but it can be adjusted using the directives provided by mod_env.

    The second most common cause of this (aside from people not outputting the required headers at all) is a result of an interaction with Perl's output buffering. To make Perl flush its buffers after each output statement, insert the following statements around the print or write statements that send your HTTP headers:

    {
     local ($oldbar) = $|;
     $cfh = select (STDOUT);
     $| = 1;
     #
     # print your HTTP headers here
     #
     $| = $oldbar;
     select ($cfh);
    }

    This is generally only necessary when you are calling external programs from your script that send output to stdout, or if there will be a long delay between the time the headers are sent and the actual content starts being emitted. To maximize performance, you should turn buffer-flushing back off (with $| = 0 or the equivalent) after the statements that send the headers, as displayed above.

    If your script isn't written in Perl, do the equivalent thing for whatever language you are using (e.g., for C, call fflush() after writing the headers).

    Another cause for the "premature end of script headers" message are the RLimitCPU and RLimitMEM directives. You may get the message if the CGI script was killed due to a resource limit.

    In addition, a configuration problem in suEXEC, mod_perl, or another third party module can often interfere with the execution of your CGI and cause the "premature end of script headers" message.


  3. Why do I keep getting "Method Not Allowed" for form POST requests?

    This is almost always due to Apache not being configured to treat the file you are trying to POST to as a CGI script. You can not POST to a normal HTML file; the operation has no meaning. See the FAQ entry on CGIs outside ScriptAliased directories for details on how to configure Apache to treat the file in question as a CGI.


  4. How can I get my script's output without Apache buffering it? Why doesn't my server push work?

    As of Apache 1.3, CGI scripts are essentially not buffered. Every time your script does a "flush" to output data, that data gets relayed on to the client. Some scripting languages, for example Perl, have their own buffering for output - this can be disabled by setting the $| special variable to 1. Of course this does increase the overall number of packets being transmitted, which can result in a sense of slowness for the end user.

    Prior to 1.3, you needed to use "nph-" scripts to accomplish non-buffering. Today, the only difference between nph scripts and normal scripts is that nph scripts require the full HTTP headers to be sent.


  5. Where can I find the "CGI specification"?

    The Common Gateway Interface (CGI) specification can be found at the original NCSA site < http://hoohoo.ncsa.uiuc.edu/cgi/interface.html>. This version hasn't been updated since 1995, and there have been some efforts to update it.

    A new draft is being worked on with the intent of making it an informational RFC; you can find out more about this project at <http://web.golux.com/coar/cgi/>.


  6. Why isn't FastCGI included with Apache any more?

    The simple answer is that it was becoming too difficult to keep the version being included with Apache synchronized with the master copy at the FastCGI web site. When a new version of Apache was released, the version of the FastCGI module included with it would soon be out of date.

    You can still obtain the FastCGI module for Apache from the master FastCGI web site.


  7. How do I enable SSI (parsed HTML)?

    SSI (an acronym for Server-Side Include) directives allow static HTML documents to be enhanced at run-time (e.g., when delivered to a client by Apache). The format of SSI directives is covered in the mod_include manual; suffice it to say that Apache supports not only SSI but xSSI (eXtended SSI) directives.

    Processing a document at run-time is called parsing it; hence the term "parsed HTML" sometimes used for documents that contain SSI instructions. Parsing tends to be resource-consumptive compared to serving static files, and is not enabled by default. It can also interfere with the cachability of your documents, which can put a further load on your server. (See the next question for more information about this.)

    To enable SSI processing, you need to

    For additional information, see the Apache Week article on Using Server Side Includes.


  8. Why don't my parsed files get cached?

    Since the server is performing run-time processing of your SSI directives, which may change the content shipped to the client, it can't know at the time it starts parsing what the final size of the result will be, or whether the parsed result will always be the same. This means that it can't generate Content-Length or Last-Modified headers. Caches commonly work by comparing the Last-Modified of what's in the cache with that being delivered by the server. Since the server isn't sending that header for a parsed document, whatever's doing the caching can't tell whether the document has changed or not - and so fetches it again to be on the safe side.

    You can work around this in some cases by causing an Expires header to be generated. (See the mod_expires documentation for more details.) Another possibility is to use the XBitHack Full mechanism, which tells Apache to send (under certain circumstances detailed in the XBitHack directive description) a Last-Modified header based upon the last modification time of the file being parsed. Note that this may actually be lying to the client if the parsed file doesn't change but the SSI-inserted content does; if the included content changes often, this can result in stale copies being cached.


  9. How can I have my script output parsed?

    So you want to include SSI directives in the output from your CGI script, but can't figure out how to do it? The short answer is "you can't." This is potentially a security liability and, more importantly, it can not be cleanly implemented under the current server API. The best workaround is for your script itself to do what the SSIs would be doing. After all, it's generating the rest of the content.

    This is a feature The Apache Group hopes to add in the next major release after 1.3.


  10. SSIs don't work for VirtualHosts and/or user home directories.

    This is almost always due to having some setting in your config file that sets "Options Includes" or some other setting for your DocumentRoot but not for other directories. If you set it inside a Directory section, then that setting will only apply to that directory.


  11. How can I use ErrorDocument and SSI to simplify customized error messages?

    Have a look at this document. It shows in example form how you can a combination of XSSI and negotiation to tailor a set of ErrorDocuments to your personal taste, and returning different internationalized error responses based on the client's native language.


  12. Why is the environment variable REMOTE_USER not set?

    This variable is set and thus available in SSI or CGI scripts if and only if the requested document was protected by access authentication. For an explanation on how to implement these restrictions, see Apache Week's articles on Using User Authentication or DBM User Authentication.

    Hint: When using a CGI script to receive the data of a HTML FORM notice that protecting the document containing the FORM is not sufficient to provide REMOTE_USER to the CGI script. You have to protect the CGI script, too. Or alternatively only the CGI script (then authentication happens only after filling out the form).


  13. How do I allow each of my user directories to have a cgi-bin directory?

    Remember that CGI execution does not need to be restricted only to cgi-bin directories. You can allow CGI script execution in arbitrary parts of your filesystem.

    There are many ways to give each user directory a cgi-bin directory such that anything requested as http://example.com/~user/cgi-bin/program will be executed as a CGI script. Two alternatives are:

    1. Place the cgi-bin directory next to the public_html directory:
      ScriptAliasMatch ^/~([^/]*)/cgi-bin/(.*) /home/$1/cgi-bin/$2
    2. Place the cgi-bin directory underneath the public_html directory:
      <Directory /home/*/public_html/cgi-bin>
          Options ExecCGI
          SetHandler cgi-script
      </Directory>

    If you are using suexec, the first technique will not work because CGI scripts must be stored under the public_html directory.