<section id="configuring">
<title>Configuring httpd to permit CGI</title>
- <p>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.</p>
-
- <note type="warning">Note: If httpd has been built with shared module
- support you need to ensure that the module is loaded; in your
+ <p>Your httpd configuration must permit CGI execution before
+ CGI programs will work. Several ways to do this are described
+ below.</p>
+
+ <p>CGI support is provided by two modules:
+ <module>mod_cgid</module> and <module>mod_cgi</module>.
+ <module>mod_cgid</module> uses a dedicated external daemon to manage
+ CGI processes and is required when httpd runs a threaded MPM (such as
+ <module>event</module> or <module>worker</module>).
+ <module>mod_cgi</module> runs CGI programs directly from within the
+ server process and is used with non-threaded MPMs like
+ <module>prefork</module>, or on Windows. From a configuration
+ standpoint they are interchangeable — the directives are the same.
+ See the <module>mod_cgi</module> and <module>mod_cgid</module>
+ reference pages for implementation details.</p>
+
+ <note type="warning">If httpd has been built with shared module
+ support, you need to ensure that the appropriate module is loaded. In your
<code>httpd.conf</code> you need to make sure the
<directive module="mod_so">LoadModule</directive>
- directive has not been commented out. A correctly configured directive
- may look like this:
-
- <highlight language="config">
- LoadModule cgid_module modules/mod_cgid.so
- </highlight>
+ directive has not been commented out. For a threaded MPM:
+<example>
+<highlight language="config">
+LoadModule cgid_module modules/mod_cgid.so
+</highlight>
+</example>
- 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:
- <highlight language="config">
- LoadModule cgi_module modules/mod_cgi.so
- </highlight></note>
+<example>
+<highlight language="config">
+LoadModule cgi_module modules/mod_cgi.so
+</highlight>
+</example>
+</note>
<section id="scriptalias">
<p>The <directive module="mod_alias">ScriptAlias</directive>
directive looks like:</p>
- <highlight language="config">
+<example>
+<highlight language="config">
ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
- </highlight>
+</highlight>
+</example>
<p>The example shown is from your default <code>httpd.conf</code>
configuration file, if you installed httpd in the default
treated as a CGI program.</p>
<p>For example, if the URL
- <code>http://www.example.com/cgi-bin/test.pl</code>
+ <code>http://www.example.com/cgi-bin/test.py</code>
is requested, httpd will attempt to execute the file
- <code>/usr/local/apache2/cgi-bin/test.pl</code>
- 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.</p>
+ <code>/usr/local/apache2/cgi-bin/test.py</code>
+ and return the output. The file must exist, be executable,
+ and produce output in the expected format; otherwise httpd
+ returns an error.</p>
</section>
<section id="nonscriptalias">
the main <code>cgi-bin</code> directory, they will need to be able to
run CGI programs elsewhere.</p>
- <p>There are two steps to allowing CGI execution in an arbitrary
- directory. First, the <code>cgi-script</code> handler must be
+ <p>Allowing CGI execution in an arbitrary directory requires
+ two steps. First, the <code>cgi-script</code> handler must be
activated using the <directive
module="mod_mime">AddHandler</directive> or <directive
module="core">SetHandler</directive> directive. Second,
file, to specify that CGI execution was permitted in a particular
directory:</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Directory "/usr/local/apache2/htdocs/somedir">
- Options +ExecCGI
+Options +ExecCGI
</Directory>
- </highlight>
+</highlight>
+</example>
<p>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 <directive module="mod_mime"
>AddHandler</directive> directive tells the server to treat all
- files with the <code>cgi</code> or <code>pl</code> extension as CGI
+ files with the <code>cgi</code> or <code>py</code> extension as CGI
programs:</p>
- <highlight language="config">
- AddHandler cgi-script .cgi .pl
- </highlight>
+<example>
+<highlight language="config">
+AddHandler cgi-script .cgi .py
+</highlight>
+</example>
</section>
<section id="htaccess">
<code>.cgi</code> in users' directories, you can use the
following configuration.</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Directory "/home/*/public_html">
- Options +ExecCGI
- AddHandler cgi-script .cgi
+Options +ExecCGI
+AddHandler cgi-script .cgi
</Directory>
- </highlight>
+</highlight>
+</example>
- <p>If you wish designate a <code>cgi-bin</code> subdirectory of
+ <p>To designate a <code>cgi-bin</code> subdirectory of
a user's directory where everything will be treated as a CGI
program, you can use the following.</p>
- <highlight language="config">
+<example>
+<highlight language="config">
<Directory "/home/*/public_html/cgi-bin">
- Options ExecCGI
- SetHandler cgi-script
+Options ExecCGI
+SetHandler cgi-script
</Directory>
- </highlight>
+</highlight>
+</example>
</section>
<section id="writing">
<title>Writing a CGI program</title>
- <p>There are two main differences between ``regular''
- programming, and CGI programming.</p>
+ <p>CGI programming differs from regular programming in two
+ ways.</p>
<p>First, all output from your CGI program must be preceded by
a <glossary>MIME-type</glossary> header. This is HTTP header that tells the client
<p>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.</p>
<p>Apart from those two things, writing a CGI program will look
<p>The following is an example CGI program that prints one
line to your browser. Type in the following, save it to a
- file called <code>first.pl</code>, and put it in your
+ file called <code>first.py</code>, and put it in your
<code>cgi-bin</code> directory.</p>
- <highlight language="perl">
-#!/usr/bin/perl
-print "Content-type: text/html\n\n";
-print "Hello, World.";
- </highlight>
-
- <p>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 <code>/usr/bin/perl</code>.
- 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.</p>
+<example>
+<highlight language="python">
+#!/usr/bin/env python3
+print("Content-type: text/html\n")
+print("Hello, World.")
+</highlight>
+</example>
+
+ <p>The first line tells the operating system which interpreter
+ to use. The first <code>print</code> call outputs the
+ content-type header followed by a blank line (the
+ <code>\n</code> in the string plus the newline that
+ <code>print()</code> adds), which marks the end of HTTP
+ headers. The second <code>print</code> call outputs the body.
+ That is all a CGI program needs to produce a response.</p>
<p>If you open your favorite browser and tell it to get the
address</p>
<example>
- http://www.example.com/cgi-bin/first.pl
+ http://www.example.com/cgi-bin/first.py
</example>
<p>or wherever you put your file, you will see the one line
<code>Hello, World.</code> 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.</p>
+ have a good chance of getting about anything working.</p>
</section>
</section>
<section id="troubleshoot">
<title>But it's still not working!</title>
- <p>There are four basic things that you may see in your browser
- when you try to access your CGI program from the web:</p>
+ <p>Four basic things may appear in your browser when you try to
+ access your CGI program from the web:</p>
<dl>
<dt>The output of your CGI program</dt>
a file sufficient permissions to be executed by <code>nobody</code>
is to give everyone execute permission on the file:</p>
- <example>
- chmod a+x first.pl
- </example>
+<example>
+<highlight language="bash">
+chmod a+x first.py
+</highlight>
+</example>
<p>Also, if your program reads from, or writes to, any other
files, those files will need to have the correct permissions
program.</p>
<p>A common manifestation of this is the path to the script
- interpreter (often <code>perl</code>) indicated in the first
+ interpreter (often <code>python3</code>) indicated in the first
line of your CGI program, which will look something like:</p>
- <highlight language="perl">
- #!/usr/bin/perl
- </highlight>
+<example>
+<highlight language="python">
+#!/usr/bin/env python3
+</highlight>
+</example>
<p>Make sure that this is in fact the path to the
interpreter.</p>
<example>
cd /usr/local/apache2/cgi-bin<br/>
- ./first.pl
+ ./first.py
</example>
- <p>(Do not call the <code>perl</code> interpreter. The shell
+ <p>(Do not call the <code>python3</code> interpreter directly. The shell
and httpd should find the interpreter using the <a
href="#pathinformation">path information</a> on the first line of
the script.)</p>
suexec will be activated.</p>
<p>Unless you fully understand suexec, you should not be using it.
- To disable suexec, simply remove (or rename) the <program>suexec</program>
+ To disable suexec, remove (or rename) the <program>suexec</program>
binary pointed to by <code>SUEXEC_BIN</code> and then restart the
server. If, after reading about <a href="../suexec.html">suexec</a>,
you still wish to use it, then run <code>suexec -V</code> to find
<p>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.</p>
<p>These variables are available to the CGI programmer, and
complete list of required variables is at
Common Gateway Interface RFC (<rfc>3875</rfc>).</p>
- <p>This simple Perl CGI program will display all of the
+ <p>This simple Python CGI program will display all of the
environment variables that are being passed around. Two
similar programs are included in the
<code>cgi-bin</code>
<a href="../env.html">add your own environment variables</a>
to the basic ones provided by default.</p>
- <highlight language="perl">
-#!/usr/bin/perl
-use strict;
-use warnings;
+<example>
+<highlight language="python">
+#!/usr/bin/env python3
+import os
-print "Content-type: text/html\n\n";
-foreach my $key (keys %ENV) {
- print "$key --> $ENV{$key}<br>";
-}
- </highlight>
+print("Content-type: text/html\n")
+for key, value in os.environ.items():
+print(f"{key} --> {value}<br>")
+</highlight>
+</example>
</section>
<section id="stdin">
<code>METHOD</code> attribute in the <code>FORM</code> tag.</p>
<p>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.</p>
+ 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.</p>
</section>
</section>
code library, or module, to do most of the grunt work for you.
This leads to fewer errors, and faster development.</p>
- <p>If you're writing CGI programs in Perl, modules are
- available on <a href="http://www.cpan.org/">CPAN</a>. The most
- popular module for this purpose is <code>CGI.pm</code>. You might
- also consider <code>CGI::Lite</code>, which implements a minimal
- set of functionality, which is all you need in most programs.</p>
+ <p>If you're writing CGI programs in Python, the standard
+ library's <code>cgi</code> module (deprecated in Python 3.11,
+ removed in 3.13) handled form parsing. For current Python
+ versions, use the <code>urllib.parse</code> 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.</p>
- <p>If you're writing CGI programs in C, there are a variety of
- options. One of these is the <code>CGIC</code> library, from
- <a href="https://web.mit.edu/wwwdev/www/cgic.html"
- >https://web.mit.edu/wwwdev/www/cgic.html</a>.</p>
</section>
<section id="moreinfo">
program was in, and, if possible, the offending code. This will
make finding your problem much simpler.</p>
- <p>Note that questions about CGI problems should <strong>never</strong>
+ <note>Questions about CGI problems should <strong>never</strong>
be posted to the httpd bug database unless you are sure you
- have found a problem in the httpd source code.</p>
+ have found a problem in the httpd source code.</note>
</section>
</manualpage>