]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
docs: howto/cgi.xml tone normalization and mod_cgi/mod_cgid explanation
authorRich Bowen <rbowen@apache.org>
Fri, 19 Jun 2026 12:23:41 +0000 (12:23 +0000)
committerRich Bowen <rbowen@apache.org>
Fri, 19 Jun 2026 12:23:41 +0000 (12:23 +0000)
- 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 <note> 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

docs/manual/howto/cgi.xml

index bbea81a5658ac2f9b0aa7d3e88844d726f9848be..4816c121a20abd3f244e6bd351c527940f2577ef 100644 (file)
   <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
@@ -116,12 +132,12 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
       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">
@@ -139,8 +155,8 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
       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,
@@ -156,22 +172,26 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
       file, to specify that CGI execution was permitted in a particular
       directory:</p>
 
-      <highlight language="config">
+<example>
+<highlight language="config">
 &lt;Directory "/usr/local/apache2/htdocs/somedir"&gt;
-    Options +ExecCGI
+Options +ExecCGI
 &lt;/Directory&gt;
-      </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">
@@ -189,23 +209,27 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
       <code>.cgi</code> in users' directories, you can use the
       following configuration.</p>
 
-      <highlight language="config">
+<example>
+<highlight language="config">
 &lt;Directory "/home/*/public_html"&gt;
-    Options +ExecCGI
-    AddHandler cgi-script .cgi
+Options +ExecCGI
+AddHandler cgi-script .cgi
 &lt;/Directory&gt;
-      </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">
 &lt;Directory "/home/*/public_html/cgi-bin"&gt;
-    Options ExecCGI
-    SetHandler cgi-script
+Options ExecCGI
+SetHandler cgi-script
 &lt;/Directory&gt;
-      </highlight>
+</highlight>
+</example>
 
     </section>
 
@@ -214,8 +238,8 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
   <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
@@ -229,7 +253,7 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
     <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
@@ -240,46 +264,44 @@ ScriptAlias "/cgi-bin/" "/usr/local/apache2/cgi-bin/"
 
       <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>
@@ -321,9 +343,11 @@ print "Hello, World.";
       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
@@ -348,12 +372,14 @@ print "Hello, World.";
       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>
@@ -395,10 +421,10 @@ print "Hello, World.";
 
       <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>
@@ -440,7 +466,7 @@ print "Hello, World.";
       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
@@ -473,7 +499,7 @@ print "Hello, World.";
       <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
@@ -481,7 +507,7 @@ print "Hello, World.";
       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>
@@ -493,16 +519,16 @@ print "Hello, World.";
       <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 --&gt; $ENV{$key}&lt;br&gt;";
-}
-      </highlight>
+print("Content-type: text/html\n")
+for key, value in os.environ.items():
+print(f"{key} --&gt; {value}&lt;br&gt;")
+</highlight>
+</example>
     </section>
 
     <section id="stdin">
@@ -542,9 +568,9 @@ foreach my $key (keys %ENV) {
       <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>
 
@@ -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.</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">
@@ -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.</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>