From: Rich Bowen Date: Fri, 19 Jun 2026 12:23:41 +0000 (+0000) Subject: docs: howto/cgi.xml tone normalization and mod_cgi/mod_cgid explanation X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2518c0d77580dd16f7b07bb15853e1409c9022c8;p=thirdparty%2Fapache%2Fhttpd.git docs: howto/cgi.xml tone normalization and mod_cgi/mod_cgid explanation - Add paragraph explaining why two CGI modules exist: mod_cgid for threaded MPMs (event, worker), mod_cgi for non-threaded (prefork) and Windows; note they are configuration-compatible - Link to both module reference pages for implementation details - Clean up LoadModule note block (remove duplicate "A correctly configured directive may look like this") - Remove "Of course" asides and "In order to" constructions - "There are two main differences" → direct statement - Move bug-database advisory into block - Convert remaining Perl references to Python git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1935512 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/docs/manual/howto/cgi.xml b/docs/manual/howto/cgi.xml index bbea81a565..4816c121a2 100644 --- a/docs/manual/howto/cgi.xml +++ b/docs/manual/howto/cgi.xml @@ -55,28 +55,42 @@
Configuring httpd to permit CGI -

In order to get your CGI programs to work properly, you'll - need to have httpd configured to permit CGI execution. There - are several ways to do this.

- - Note: If httpd has been built with shared module - support you need to ensure that the module is loaded; in your +

Your httpd configuration must permit CGI execution before + CGI programs will work. Several ways to do this are described + below.

+ +

CGI support is provided by two modules: + mod_cgid and mod_cgi. + mod_cgid uses a dedicated external daemon to manage + CGI processes and is required when httpd runs a threaded MPM (such as + event or worker). + mod_cgi runs CGI programs directly from within the + server process and is used with non-threaded MPMs like + prefork, or on Windows. From a configuration + standpoint they are interchangeable — the directives are the same. + See the mod_cgi and mod_cgid + reference pages for implementation details.

+ + If httpd has been built with shared module + support, you need to ensure that the appropriate module is loaded. In your httpd.conf you need to make sure the LoadModule - directive has not been commented out. A correctly configured directive - may look like this: - - - LoadModule cgid_module modules/mod_cgid.so - + directive has not been commented out. For a threaded MPM: + + +LoadModule cgid_module modules/mod_cgid.so + + - On Windows, or using a non-threaded MPM like prefork, A correctly - configured directive may look like this: + For Windows, or a non-threaded MPM like prefork: - - LoadModule cgi_module modules/mod_cgi.so - + + +LoadModule cgi_module modules/mod_cgi.so + + +
@@ -94,9 +108,11 @@

The ScriptAlias directive looks like:

- + + ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" - + +

The example shown is from your default httpd.conf configuration file, if you installed httpd in the default @@ -116,12 +132,12 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" treated as a CGI program.

For example, if the URL - http://www.example.com/cgi-bin/test.pl + http://www.example.com/cgi-bin/test.py is requested, httpd will attempt to execute the file - /usr/local/apache2/cgi-bin/test.pl - and return the output. Of course, the file will have to - exist, and be executable, and return output in a particular - way, or httpd will return an error message.

+ /usr/local/apache2/cgi-bin/test.py + and return the output. The file must exist, be executable, + and produce output in the expected format; otherwise httpd + returns an error.

@@ -139,8 +155,8 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" the main cgi-bin directory, they will need to be able to run CGI programs elsewhere.

-

There are two steps to allowing CGI execution in an arbitrary - directory. First, the cgi-script handler must be +

Allowing CGI execution in an arbitrary directory requires + two steps. First, the cgi-script handler must be activated using the AddHandler or SetHandler directive. Second, @@ -156,22 +172,26 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" file, to specify that CGI execution was permitted in a particular directory:

- + + <Directory "/usr/local/apache2/htdocs/somedir"> - Options +ExecCGI +Options +ExecCGI </Directory> - + +

The above directive tells httpd to permit the execution of CGI files. You will also need to tell the server what files are CGI files. The following AddHandler directive tells the server to treat all - files with the cgi or pl extension as CGI + files with the cgi or py extension as CGI programs:

- - AddHandler cgi-script .cgi .pl - + + +AddHandler cgi-script .cgi .py + +
@@ -189,23 +209,27 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/" .cgi in users' directories, you can use the following configuration.

- + + <Directory "/home/*/public_html"> - Options +ExecCGI - AddHandler cgi-script .cgi +Options +ExecCGI +AddHandler cgi-script .cgi </Directory> - + + -

If you wish designate a cgi-bin subdirectory of +

To designate a cgi-bin subdirectory of a user's directory where everything will be treated as a CGI program, you can use the following.

- + + <Directory "/home/*/public_html/cgi-bin"> - Options ExecCGI - SetHandler cgi-script +Options ExecCGI +SetHandler cgi-script </Directory> - + +
@@ -214,8 +238,8 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
Writing a CGI program -

There are two main differences between ``regular'' - programming, and CGI programming.

+

CGI programming differs from regular programming in two + ways.

First, all output from your CGI program must be preceded by a MIME-type header. This is HTTP header that tells the client @@ -229,7 +253,7 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"

Secondly, your output needs to be in HTML, or some other format that a browser will be able to display. Most of the time, this will be HTML, but occasionally you might write a CGI - program that outputs a gif image, or other non-HTML + program that outputs a GIF image, or other non-HTML content.

Apart from those two things, writing a CGI program will look @@ -240,46 +264,44 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"

The following is an example CGI program that prints one line to your browser. Type in the following, save it to a - file called first.pl, and put it in your + file called first.py, and put it in your cgi-bin directory.

- -#!/usr/bin/perl -print "Content-type: text/html\n\n"; -print "Hello, World."; - - -

Even if you are not familiar with Perl, you should be able - to see what is happening here. The first line tells httpd - (or whatever shell you happen to be running under) that this - program can be executed by feeding the file to the - interpreter found at the location /usr/bin/perl. - The second line prints the content-type declaration we - talked about, followed by two carriage-return newline pairs. - This puts a blank line after the header, to indicate the end - of the HTTP headers, and the beginning of the body. The third - line prints the string "Hello, World.". And that's the end - of it.

+ + +#!/usr/bin/env python3 +print("Content-type: text/html\n") +print("Hello, World.") + + + +

The first line tells the operating system which interpreter + to use. The first print call outputs the + content-type header followed by a blank line (the + \n in the string plus the newline that + print() adds), which marks the end of HTTP + headers. The second print call outputs the body. + That is all a CGI program needs to produce a response.

If you open your favorite browser and tell it to get the address

- http://www.example.com/cgi-bin/first.pl + http://www.example.com/cgi-bin/first.py

or wherever you put your file, you will see the one line Hello, World. appear in your browser window. It's not very exciting, but once you get that working, you'll - have a good chance of getting just about anything working.

+ have a good chance of getting about anything working.

But it's still not working! -

There are four basic things that you may see in your browser - when you try to access your CGI program from the web:

+

Four basic things may appear in your browser when you try to + access your CGI program from the web:

The output of your CGI program
@@ -321,9 +343,11 @@ print "Hello, World."; a file sufficient permissions to be executed by nobody is to give everyone execute permission on the file:

- - chmod a+x first.pl - + + +chmod a+x first.py + +

Also, if your program reads from, or writes to, any other files, those files will need to have the correct permissions @@ -348,12 +372,14 @@ print "Hello, World."; program.

A common manifestation of this is the path to the script - interpreter (often perl) indicated in the first + interpreter (often python3) indicated in the first line of your CGI program, which will look something like:

- - #!/usr/bin/perl - + + +#!/usr/bin/env python3 + +

Make sure that this is in fact the path to the interpreter.

@@ -395,10 +421,10 @@ print "Hello, World."; cd /usr/local/apache2/cgi-bin
- ./first.pl + ./first.py
-

(Do not call the perl interpreter. The shell +

(Do not call the python3 interpreter directly. The shell and httpd should find the interpreter using the path information on the first line of the script.)

@@ -440,7 +466,7 @@ print "Hello, World."; suexec will be activated.

Unless you fully understand suexec, you should not be using it. - To disable suexec, simply remove (or rename) the suexec + To disable suexec, remove (or rename) the suexec binary pointed to by SUEXEC_BIN and then restart the server. If, after reading about suexec, you still wish to use it, then run suexec -V to find @@ -473,7 +499,7 @@ print "Hello, World.";

During the CGI transaction, the server and the browser also set environment variables, so that they can communicate with one another. These are things like the browser type - (Chrome, Firefox, Lynx), the server type (Apache httpd, Nginx, IIS), + (Chrome, Firefox, Lynx), the server type (httpd, Nginx, IIS), the name of the CGI program that is being run, and so on.

These variables are available to the CGI programmer, and @@ -481,7 +507,7 @@ print "Hello, World."; complete list of required variables is at Common Gateway Interface RFC (3875).

-

This simple Perl CGI program will display all of the +

This simple Python CGI program will display all of the environment variables that are being passed around. Two similar programs are included in the cgi-bin @@ -493,16 +519,16 @@ print "Hello, World."; add your own environment variables to the basic ones provided by default.

- -#!/usr/bin/perl -use strict; -use warnings; + + +#!/usr/bin/env python3 +import os -print "Content-type: text/html\n\n"; -foreach my $key (keys %ENV) { - print "$key --> $ENV{$key}<br>"; -} - +print("Content-type: text/html\n") +for key, value in os.environ.items(): +print(f"{key} --> {value}<br>") + +
@@ -542,9 +568,9 @@ foreach my $key (keys %ENV) { METHOD attribute in the FORM tag.

Your program is then responsible for splitting that string - up into useful information. Fortunately, there are libraries - and modules available to help you process this data, as well - as handle other of the aspects of your CGI program.

+ up into useful information. Fortunately, libraries + and modules are available to help you process this data, as well + as handle other aspects of your CGI program.

@@ -555,16 +581,14 @@ foreach my $key (keys %ENV) { code library, or module, to do most of the grunt work for you. This leads to fewer errors, and faster development.

-

If you're writing CGI programs in Perl, modules are - available on CPAN. The most - popular module for this purpose is CGI.pm. You might - also consider CGI::Lite, which implements a minimal - set of functionality, which is all you need in most programs.

+

If you're writing CGI programs in Python, the standard + library's cgi module (deprecated in Python 3.11, + removed in 3.13) handled form parsing. For current Python + versions, use the urllib.parse module to parse + query strings and form data. For more complex applications, + consider a lightweight WSGI framework, though that moves + beyond the scope of traditional CGI.

-

If you're writing CGI programs in C, there are a variety of - options. One of these is the CGIC library, from - https://web.mit.edu/wwwdev/www/cgic.html.

@@ -581,8 +605,8 @@ foreach my $key (keys %ENV) { program was in, and, if possible, the offending code. This will make finding your problem much simpler.

-

Note that questions about CGI problems should never + Questions about CGI problems should never be posted to the httpd bug database unless you are sure you - have found a problem in the httpd source code.

+ have found a problem in the httpd source code.