CGI & Web Development Glossary

Key terms from the CGI/Perl era of web development (1993–2005). Each term explained in plain language with links to related scripts and articles on this site. Use the anchor links to jump directly to any term, or bookmark individual entries (e.g. /glossary/#formmail).

A

Apache

The open-source HTTP server that dominated the web from 1996 onward, when it overtook NCSA HTTPd. Apache was the server most CGI scripts ran on. It supported CGI execution through its mod_cgi module and used .htaccess files for per-directory configuration. The name is sometimes said to come from “a patchy server” — a collection of patches applied to the original NCSA code. By 2005, Apache served over 70% of all websites on the internet.

ASCII Mode

A file transfer mode in FTP that converts line endings between operating systems (e.g. \r\n on Windows to \n on Unix). CGI scripts written on Windows had to be uploaded in ASCII mode, not binary mode, or the Perl interpreter would fail on the carriage return characters. This was one of the most common causes of the dreaded 500 Internal Server Error for beginners installing their first CGI script.

C

CGI (Common Gateway Interface)

The protocol specification — formally defined in RFC 3875 (2004, though the standard existed informally since 1993) — that allows web servers to execute external programs and return their output as HTTP responses. CGI was the first widely adopted method for creating dynamic, interactive web pages. When a browser requested a URL mapped to a CGI script, the web server would set a collection of environment variables (such as QUERY_STRING, REQUEST_METHOD, and CONTENT_TYPE), execute the script as a separate process, and pipe the script’s standard output back to the client as the HTTP response.

The script was responsible for outputting HTTP headers (at minimum, Content-type: text/html) followed by a blank line and the response body. CGI scripts could be written in any language — Perl, C, Python, shell scripts — but Perl became the dominant choice. The main drawback of CGI was performance: every request spawned a new process, which was expensive on busy servers. This led to alternatives like mod_perl and FastCGI. For a deeper look at CGI’s role in web history, see our article on CGI technology and the early web.

cgi-bin

The server directory designated for storing executable CGI scripts. On most Apache installations, this was located at /usr/lib/cgi-bin/ or /home/username/cgi-bin/. Files placed in this directory were treated as programs to be executed rather than static files to be served. When you saw a URL like http://example.com/cgi-bin/formmail.pl, the cgi-bin part told the web server to run the script rather than display its source code.

The directory needed specific permissions and Apache ScriptAlias configuration to function. Most shared hosting providers in the 1990s provided a pre-configured cgi-bin directory with each account. The concept is explored in detail in our history of CGI technology.

chmod

The Unix command for changing file permissions. For CGI scripts, the critical command was chmod 755 script.pl, which set the file to be readable and executable by everyone but writable only by the owner. The three digits represent owner (7 = read+write+execute), group (5 = read+execute), and others (5 = read+execute). Data files written by CGI scripts (like guestbook entries or counter logs) typically needed chmod 666 (read+write for all) or chmod 777 for directories. Getting permissions wrong was one of the most common installation problems — nearly every script readme from the 1990s included a section explaining chmod.

Content-type

The HTTP header that tells the browser what type of data is being returned. Every CGI script had to output this header before any content. The standard opening line of a Perl CGI script was print "Content-type: text/html\n\n"; — the double newline separated headers from the body. Forgetting this header or placing any output before it caused the server to return a 500 Internal Server Error. See also MIME type.

CPAN

The Comprehensive Perl Archive Network — a repository of over 250,000 Perl modules. CPAN provided ready-made solutions for common CGI tasks: CGI.pm for form parsing, MIME::Lite for email, DBI for database access, and thousands more. Many shared hosting providers did not allow users to install CPAN modules, which is one reason self-contained scripts like those in Matt’s Script Archive were so popular — they required no external dependencies.

CRLF

Carriage Return + Line Feed (\r\n) — the line ending used by Windows and required by HTTP headers (RFC 2616). Unix systems use just \n (LF). When a Perl script written on Windows was uploaded to a Unix server in binary FTP mode, the extra \r characters caused the shebang line to fail — the system would look for /usr/bin/perl\r instead of /usr/bin/perl. This was one of the most frequent and confusing errors for CGI beginners. See ASCII mode.

D

DNS (Domain Name System)

The system that translates human-readable domain names (like worldwidemart.com) into IP addresses that computers use to locate servers. In the CGI era, webmasters had to understand DNS to point their domains to their hosting provider’s server. Changing nameservers often took 24–72 hours to propagate worldwide, a delay that caused confusion when setting up new sites or migrating between hosts.

E

Environment Variables

Data passed from the web server to a CGI script via the operating system environment. Key variables included QUERY_STRING (data from the URL), REQUEST_METHOD (GET or POST), REMOTE_ADDR (visitor’s IP address), HTTP_REFERER (the referring page), SERVER_NAME, and CONTENT_LENGTH. In Perl, these were accessed through the %ENV hash — for example, $ENV{'QUERY_STRING'}. Matt’s scripts frequently used environment variables to determine the visitor’s browser, IP address, and the form data submitted. A complete list of standard CGI environment variables is defined in RFC 3875.

F

FastCGI

An improved version of the CGI protocol that keeps script processes running persistently rather than spawning a new process for each request. Developed by Open Market in the mid-1990s, FastCGI addressed CGI’s main performance bottleneck. A FastCGI application starts once and handles multiple requests through a socket connection, dramatically reducing overhead. While traditional CGI might handle 10–50 requests per second, a FastCGI process could handle hundreds. FastCGI influenced later technologies like PSGI in Perl and WSGI in Python.

Flat File

A plain text file used to store data instead of a database. Most CGI scripts of the 1990s used flat files because shared hosting rarely included database access. Matt’s Guestbook stored entries in an HTML file, Counter stored hit counts in a text file, and WWWBoard saved each message as a separate HTML file. Flat files were simple but caused problems with concurrent access — if two visitors submitted forms simultaneously, data could be corrupted. Perl’s flock() function was used to lock files during write operations.

FormMail

A Perl CGI script written by Matt Wright that processed HTML form data and sent it as email to a specified recipient. FormMail was the most downloaded CGI script in history, with over 2 million installations at its peak. It solved the fundamental problem of “how do I make a contact form work?” in an era before PHP’s mail() function or any form-processing SaaS existed. Webmasters pointed their HTML form’s action attribute at the script, set configuration variables (recipient email, required fields, redirect URL), and had a working contact form in minutes.

Early versions had a critical security flaw: they could be exploited as open email relays by spammers, which prompted the NMS Project to create a secure replacement. Matt later addressed the vulnerabilities and eventually launched FormMail.com as a hosted service. Read more about FormMail →

FTP (File Transfer Protocol)

The standard method for uploading files to a web server throughout the 1990s and 2000s. Before SFTP, SCP, or Git deployment, every CGI script was installed by FTPing the .pl file to the server’s cgi-bin directory. Popular FTP clients included WS_FTP, CuteFTP, and later FileZilla. The critical choice was between ASCII mode (for scripts and text files) and binary mode (for images and archives). Using the wrong mode was one of the most common CGI installation mistakes.

G

GET Method

An HTTP request method that sends form data appended to the URL as a query string (e.g. ?name=John&[email protected]). GET requests have a length limit (typically 2,048 characters in older browsers), are visible in the browser’s address bar, and are cached by browsers and proxies. CGI scripts accessed GET data through the QUERY_STRING environment variable. GET was appropriate for search forms and read-only operations but not for submitting sensitive data. See also POST method.

GIF

Graphics Interchange Format — the dominant image format on the early web. GIF supported transparency and animation, making it essential for CGI-generated content. Matt’s Counter script worked by dynamically selecting individual GIF digit images and displaying them inline. The Random Image and SSI Random Image scripts selected and displayed random GIFs from a directory. GIF’s 256-color palette was sufficient for web graphics of the era.

Guestbook

A web application that allowed visitors to leave their name, email, homepage URL, and a message. Guestbooks were a defining feature of personal websites in the late 1990s — before blog comments, social media likes, or any other form of visitor interaction. Matt’s Guestbook script was one of the most popular implementations. Entries were stored in a flat HTML file, with new messages prepended to the top. Guestbooks were eventually replaced by blog comments (Movable Type, WordPress) and later by social media entirely.

H

Hit Counter

A script that tracked and displayed the number of page visits, typically shown as a row of digit images on the page. Hit counters were a staple of 1990s web design, often placed prominently on homepages as a badge of popularity. Matt’s Script Archive offered two versions: Counter (graphical, using GIF digit images) and TextCounter (plain text output via SSI). Hit counters were eventually made obsolete by server-side analytics tools like Webalizer, AWStats, and ultimately Google Analytics (2005).

.htaccess

A per-directory configuration file for the Apache web server. Webmasters used .htaccess to enable CGI execution, set up custom error pages, control access with passwords, configure URL rewrites, and define MIME types. A common .htaccess entry for CGI was AddHandler cgi-script .pl .cgi, which told Apache to execute Perl files as programs. On shared hosting, .htaccess was often the only way to change server configuration since users had no access to the main httpd.conf file.

HTTP (HyperText Transfer Protocol)

The application-level protocol that governs communication between web browsers and web servers. HTTP defines request methods (GET, POST, HEAD, etc.), status codes (200 OK, 404 Not Found, 500 Internal Server Error), and the header/body structure of messages. CGI scripts had to generate valid HTTP responses, starting with headers like Content-type: text/html. The protocol operated over TCP port 80 (HTTPS on 443). HTTP/1.0 (1996) and HTTP/1.1 (1997) were the versions used during the CGI era.

HTTP Headers

Key-value pairs sent at the beginning of HTTP requests and responses. CGI scripts received request headers through environment variables (e.g. HTTP_USER_AGENT, HTTP_REFERER) and had to output response headers before any content. The minimum output was Content-type: text/html\n\n. Scripts could also set cookies (Set-Cookie), control caching (Cache-Control), or redirect the browser (Location: http://example.com). Matt’s FormMail generated redirect headers to send users to a thank-you page after form submission.

I

ISP (Internet Service Provider)

A company providing internet access and, in the 1990s, often bundled web hosting. Many early websites were hosted on ISP-provided space with URLs like http://www.isp.net/~username/. ISP hosting typically included a cgi-bin directory, limited disk space (1–10 MB), and FTP access. The quality of CGI support varied widely — some ISPs pre-installed Perl modules, while others restricted script execution for security reasons. Matt’s scripts were designed to work on the widest possible range of ISP hosting environments.

L

Luhn Algorithm

A checksum formula used to validate credit card numbers. Matt’s Credit Card Verifier script used the Luhn algorithm to check whether a card number was structurally valid before processing. The algorithm works by doubling every second digit from the right, summing all digits, and checking if the total is divisible by 10. It catches accidental typos but does not verify whether a card is active or has funds. The Luhn algorithm remains in use today in every payment system.

M

MIME Type

Multipurpose Internet Mail Extensions type — a standardized label that tells the browser how to handle received content. Common MIME types in CGI: text/html for web pages, text/plain for raw text, image/gif for GIF images, and application/octet-stream for file downloads. Every CGI script output began with a Content-type header specifying the MIME type. The server’s mime.types file or .htaccess directives mapped file extensions to MIME types for static files.

mod_perl

An Apache module that embedded a persistent Perl interpreter directly into the web server process. Instead of spawning a new Perl process for each request (as standard CGI did), mod_perl kept the interpreter running and cached compiled scripts in memory. This improved performance by 10–100x compared to plain CGI. mod_perl also provided a powerful API for interacting with Apache’s internals. However, it required more memory, was harder to configure, and was not available on most shared hosting. It was primarily used on dedicated servers running high-traffic Perl applications.

N

NCSA HTTPd

The web server developed at the National Center for Supercomputing Applications (University of Illinois) that was the first widely used HTTP server and the origin of CGI support. NCSA HTTPd introduced the cgi-bin convention and the environment variable interface that became the CGI standard. Development stalled in 1995, and the Apache project forked from NCSA HTTPd, taking the CGI conventions with it. The “NCSA” in the server’s name is the same center that produced the Mosaic web browser.

NMS Project

A project by the London Perl Mongers (initiated around 2001–2002) that created secure, drop-in replacements for Matt’s Script Archive scripts. “NMS” stood for “Not Matt’s Scripts” (or “New Matt’s Scripts” depending on the source). The NMS versions addressed security vulnerabilities — particularly in FormMail — by adding input validation, taint mode, and anti-spam features. They were designed as configuration-compatible replacements: a webmaster could swap in the NMS version without changing their HTML forms. The project was hosted on SourceForge at nms-cgi.sourceforge.net. For more on the NMS Project and its historical context, see our history section.

P

PATH_INFO

A CGI environment variable containing the extra path information appended after the script name in a URL. For example, in /cgi-bin/script.pl/page/about, the PATH_INFO would be /page/about. This allowed a single CGI script to serve multiple “pages” without separate files. Many early web applications used PATH_INFO as a primitive routing mechanism before URL rewriting became common through .htaccess and mod_rewrite.

Perl

The programming language created by Larry Wall in 1987 that became the dominant language for CGI web development from 1993 until the early 2000s. Perl’s strengths for web work were formidable: powerful text processing with built-in regular expressions, the CGI.pm module for form handling, straightforward file I/O, and the vast CPAN module library. The phrase “Perl — the duct tape of the internet” captured its role as the go-to language for gluing together web functionality.

Every script in Matt’s Script Archive was written in Perl 5. The shebang line #!/usr/bin/perl was the universal starting point. Perl’s dominance in web development declined after 2000 as PHP rose to prominence, but Perl remains in active development and use today, particularly in system administration and bioinformatics.

PHP

A server-side scripting language created by Rasmus Lerdorf in 1995 that gradually replaced Perl as the dominant web development language. PHP could be embedded directly in HTML files (unlike Perl CGI, which had to output all HTML from the script), was easier to learn, and ran as an Apache module (mod_php) rather than through the slower CGI interface. By 2003–2004, PHP had overtaken Perl for new web projects. WordPress (2003), built on PHP, eventually made hand-coded CGI scripts unnecessary for most use cases.

POST Method

An HTTP request method that sends form data in the request body rather than the URL. POST has no practical size limit, keeps data out of the address bar and server logs, and is appropriate for submitting forms, uploading files, or modifying server-side data. CGI scripts read POST data from STDIN, with the CONTENT_LENGTH environment variable indicating how many bytes to read. Matt’s FormMail accepted both GET and POST, but POST was the recommended method for contact forms. See also GET method.

PSGI (Perl Web Server Gateway Interface)

A specification (inspired by Python’s WSGI and Ruby’s Rack) that defines a standard interface between Perl web frameworks and web servers. Published in 2009, PSGI replaced the aging CGI model for modern Perl web applications. Instead of a script outputting headers and HTML to STDOUT, a PSGI app is a code reference that receives a request environment hash and returns an array of status code, headers, and body. The Plack toolkit provides PSGI middleware and server adapters. PSGI represents the evolution of the same concept that CGI introduced in 1993.

Q

QUERY_STRING

The environment variable containing the portion of the URL after the ? character. For /cgi-bin/search.pl?q=perl&page=2, the QUERY_STRING is q=perl&page=2. CGI scripts parsed this string to extract form parameters — Perl’s CGI.pm module handled this automatically, but many early scripts (including Matt’s) parsed it manually by splitting on & and = and decoding URL-encoded characters. Improper parsing of QUERY_STRING was a common source of security vulnerabilities.

R

Referer

The HTTP header (intentionally misspelled in the original HTTP specification) that contains the URL of the page that linked to the current request. CGI scripts accessed it via the HTTP_REFERER environment variable. Matt’s FormMail used the referer to validate that form submissions came from an authorized page — though this check was easily spoofed. Hit counters and analytics scripts used the referer to track where visitors came from. The NMS replacement for FormMail added a configurable list of allowed referers as a security measure.

Regular Expression (Regex)

Perl’s built-in pattern matching system, accessed through operators like =~, m//, and s///. Regular expressions were central to CGI programming: validating email addresses (/^[\w.+-]+@[\w.-]+\.\w+$/), parsing form data, extracting values from strings, and sanitizing user input. Perl’s regex engine was so powerful that it influenced regex implementations in every subsequent language. Larry Wall once said Perl was designed to make easy things easy and hard things possible — and regex was the mechanism that delivered on both promises.

RFC 3875

The formal specification of the Common Gateway Interface, published in October 2004. RFC 3875 documented the protocol that had been in informal use since 1993, defining the standard environment variables, the request/response model, and the interface between web servers and CGI programs. The RFC was authored by David Robinson and Ken Coar, codifying practices that had evolved through NCSA HTTPd and Apache. Despite being published in 2004, the RFC described technology that was already being superseded by mod_perl, PHP, and other alternatives.

S

Sendmail

The Unix mail transfer agent (MTA) that CGI scripts used to send email. Matt’s FormMail relied on sendmail to deliver form submissions — the script piped the formatted message to /usr/lib/sendmail -t (or /usr/sbin/sendmail -t) using Perl’s open(MAIL, "|$mailprog -t") construct. The -t flag told sendmail to extract recipient addresses from the message headers. Finding the correct path to sendmail was a common installation task, and misconfigured sendmail was a frequent reason for FormMail failing to deliver email. Alternatives like Postfix and qmail later replaced sendmail on many servers, but they maintained the same command-line interface for backward compatibility.

Server Side Includes (SSI)

A simple server-side scripting language that allowed webmasters to include dynamic content in HTML pages using special comment-like directives. The most common SSI directives were <!--#include file="header.html"--> (insert another file), <!--#echo var="DATE_LOCAL"--> (display server variables), and <!--#exec cgi="/cgi-bin/counter.pl"--> (execute a CGI script and embed its output). SSI required files to have a .shtml extension (or Apache configured to parse all .html files).

Matt’s TextCounter and SSI Random Image scripts were designed specifically to work within SSI directives, outputting just a fragment of HTML that was embedded in the surrounding page. SSI was a precursor to modern template includes and server-side rendering.

Shebang (#!)

The two-character sequence #! at the very beginning of a script file, followed by the path to the interpreter. For Perl CGI scripts, the standard shebang line was:

#!/usr/bin/perl

This told the Unix operating system to execute the file using the Perl interpreter at that path. The shebang had to be the absolute first line of the file — no blank lines, no comments, no BOM (byte order mark) before it. Common variations included #!/usr/local/bin/perl (FreeBSD, some shared hosts) and #!/usr/bin/env perl (portable, finds Perl in the system PATH). Getting the shebang path wrong was one of the top three reasons CGI scripts failed to execute, alongside incorrect file permissions and CRLF line endings.

Shared Hosting

A hosting model where multiple websites share a single web server. Shared hosting was the most common and affordable way to host a website in the 1990s and 2000s. Each user had their own directory, cgi-bin, and FTP access, but shared the server’s CPU, memory, and Apache installation. Matt’s scripts were specifically designed for shared hosting environments — they required no database, no special Perl modules, no root access, and no server configuration beyond a working cgi-bin. This universal compatibility was a key reason for their enormous popularity.

STDIN / STDOUT

Standard Input and Standard Output — the Unix I/O streams that CGI used for communication between the web server and the script. The server sent POST request data to the script via STDIN, and the script wrote its HTTP response (headers + body) to STDOUT. In Perl, print writes to STDOUT by default, so print "Content-type: text/html\n\n"; sent the response header directly to the web server. STDIN was read with read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'}) to capture POST form data. This simple pipe-based model is what made CGI language-agnostic — any program that could read STDIN and write to STDOUT could be a CGI script.

T

Taint Mode

Perl’s built-in security feature, enabled by adding -T to the shebang line: #!/usr/bin/perl -T. When taint mode was active, Perl tracked all data that came from external sources (form input, environment variables, file reads) and refused to use “tainted” data in potentially dangerous operations like system calls, file operations, or email piping — unless the data was first validated through a regular expression match.

Taint mode was a powerful defense against injection attacks. The original Matt’s scripts did not use taint mode, which was one of the main criticisms from the Perl community. The NMS Project replacements enabled taint mode by default and demonstrated proper input sanitization techniques.

tar.gz

The standard archive format on Unix systems, combining tar (tape archive, which bundles multiple files) and gzip (compression). CGI script distributions were commonly packaged as .tar.gz files. To install, you would download the archive, run tar -xzf script.tar.gz to extract it, then upload the files via FTP. Windows users often needed WinZip or 7-Zip to extract these archives. Matt’s scripts were distributed both as individual .pl files and as tar.gz bundles containing the script, readme, and any associated files.

U

Unix Permissions

The file access control system on Unix and Linux servers, represented as a three-digit octal number or a nine-character string (e.g. rwxr-xr-x). For CGI scripts, the essential permission was 755 (rwxr-xr-x): owner can read, write, and execute; group and others can read and execute. Data files needed 666 (rw-rw-rw-) for read/write access. Directories needed 755 or 777. On shared hosting with suexec, scripts might need 700 instead. Permissions were set via chmod on the command line or through the FTP client’s file properties dialog.

URL Encoding

The process of converting special characters into percent-encoded format for safe transmission in URLs. Spaces become + or %20, ampersands become %26, and non-ASCII characters are encoded as UTF-8 byte sequences prefixed with %. CGI scripts had to decode URL-encoded form data from QUERY_STRING and POST bodies. The standard Perl decoding was: $value =~ tr/+/ /; $value =~ s/%([a-fA-F0-9]{2})/pack("C", hex($1))/eg;. Perl’s CGI.pm module handled this automatically, but many hand-written scripts (including early Matt’s scripts) decoded manually.

V

Virtual Host

An Apache configuration that allows a single server to host multiple websites, each with its own domain name. Before virtual hosting, each website required a dedicated IP address. Apache’s name-based virtual hosts (introduced in HTTP/1.1’s Host header) allowed thousands of sites to share one IP. Each virtual host block defined the domain, document root, cgi-bin location, and other settings. Shared hosting providers used virtual hosts to serve hundreds or thousands of customer websites from a single server. The configuration was typically in httpd.conf or individual files in a vhosts directory.

W

Web Server

Software that listens for HTTP requests and returns responses — either static files (HTML, images) or the output of dynamic programs (CGI scripts, PHP pages). In the CGI era, Apache was the dominant web server, with NCSA HTTPd and Microsoft IIS as alternatives. The web server’s role in CGI was to receive the HTTP request, determine that the requested URL maps to a CGI program, set the appropriate environment variables, execute the script, and relay its output back to the client’s browser.

World Wide Mart

World Wide Mart, Inc. was a hosting company founded by Dave Jackson in Naples, Florida in 1994. The company operated the domain worldwidemart.com and provided the server space where Matt Wright first published his script collection. The URL http://www.worldwidemart.com/scripts/ was the original address of Matt’s Script Archive before Matt moved the collection to scriptarchive.com. This site preserves the history and documentation of that original collection. Read more about WorldWideMart.com →

WWWBoard

A Perl CGI discussion forum script by Matt Wright that allowed threaded conversations on a website. Each message was stored as a separate HTML flat file, with an index page listing all threads. Users could post new topics and reply to existing messages. WWWBoard predated database-driven forum software like phpBB (2000) and vBulletin (2000) by several years. It included a companion admin script (WWWAdmin) for managing posts. Read more about WWWBoard →

Related Pages

The History of CGI Technology

How the Common Gateway Interface transformed the web from static pages to interactive applications.

Script Archive

Browse the complete collection of Matt Wright’s CGI scripts with documentation and source code.

Full History

The complete history of Matt’s Script Archive from 1995 to 2009.