YouTip LogoYouTip

Perl Cgi Programming

Perl CGI Programming

Perl CGI Programming


What is CGI

CGI is currently maintained by NCSA, which defines CGI as follows:

CGI (Common Gateway Interface) is a program that runs on a server (such as an HTTP server) and provides an interface to communicate with client HTML pages.


Web Browsing

To better understand how CGI works, we can look at the process of clicking a link or URL on a webpage:

  1. Use your browser to visit the URL and connect to the HTTP web server.
  2. After receiving the request information, the web server parses the URL and checks if the requested file exists on the server. If it exists, it returns the file content; otherwise, it returns an error message.
  3. The browser receives the information from the server and displays the received file or error message.

CGI programs can be Python scripts, PERL scripts, SHELL scripts, C or C++ programs, etc.


CGI Architecture Diagram

Image 1: cgiarch


Web Server Support and Configuration

Before you start CGI programming, ensure your web server supports CGI and has configured the CGI handler.

Apache supports CGI configuration:

Set up the CGI directory:

ScriptAlias /cgi-bin/ /var/www/cgi-bin/

All HTTP servers store CGI programs in a pre-configured directory. This directory is called the CGI directory and, by convention, it is named /var/www/cgi-bin.

CGI files have the extension .cgi, and Perl scripts can also use the .pl extension.

By default, the Linux server is configured to run the cgi-bin directory at /var/www.

If you want to specify a different directory for running CGI scripts, you can modify the httpd.conf configuration file as shown below:

<Directory "/var/www/cgi-bin">
    AllowOverride None
    Options +ExecCGI
    Order allow,deny
    Allow from all
</Directory>

Add the .pl suffix in AddHandler, so we can access Perl script files ending with .pl:

AddHandler cgi-script .cgi .pl .py

First CGI Program

Below, we create a test.cgi file with the following code:

test.cgi Code

#!/usr/bin/perl
print "Content-type:text/htmlrnrn";
print '<html>';
print '<head>';
print '<meta charset="utf-8">';
print '<title>()</title>';
print '</head>';
print '<body>';
print '<h2>Hello Word! </h2>';
print '<p>This is the first CGI program from .</p>';
print '</body>';
print '</html>';
1;

Then open http://localhost/cgi-bin/test.cgi in your browser, and the output will be as follows:

Image 2

The first line of the script outputs "Content-type:text/htmlrnrn" to the browser, informing it that the content type is "text/html".


HTTP Headers

The "Content-type:text/html" in the test.cgi file is part of the HTTP header, which is sent to the browser to tell it the content type of the file.

The format of the HTTP header is as follows:

HTTP Field Name: Field Content

For example:

Content-type:text/htmlrnrn

The following table introduces the commonly used information in HTTP headers for CGI programs:

Header Description
Content-type: MIME information corresponding to the requested entity. For example: Content-type:text/html
Expires: Date Date and time when the response expires
Location: URL Used to redirect the recipient to a non-requested URL to complete the request or identify a new resource
Last-modified: Date Last modification time of the requested resource
Content-length: N Content length of the request
Set-Cookie: String Set Http Cookie

CGI Environment Variables

All CGI programs receive the following environment variables, which play an important role in CGI programs:

Variable Name Description
CONTENT_TYPE The value of this environment variable indicates the MIME type of the transmitted information. Currently, the environment variable CONTENT_TYPE is generally: application/x-www-form-urlencoded, indicating that the data comes from an HTML form.
CONTENT_LENGTH If the server transmits information to the CGI program via POST, this environment variable indicates the number of bytes of valid data that can be read from standard input STDIN. This environment variable must be used when reading the input data.
HTTP_COOKIE COOKIE content within the client.
HTTP_USER_AGENT Provides client browser information including version number or other proprietary data.
PATH_INFO The value of this environment variable represents other path information immediately following the CGI program name. It often appears as a parameter of the CGI program.
QUERY_STRING If the server transmits information to the CGI program via GET, the value of this environment variable is the transmitted information. This information follows the CGI program name, separated by a question mark '?'.
REMOTE_ADDR The value of this environment variable is the IP address of the client sending the request, such as 192.168.1.67 above. This value always exists. It is the unique identifier that the web client needs to provide to the web server, and it can be used in CGI programs to distinguish different web clients.
REMOTE_HOST The value of this environment variable contains the hostname of the client sending the CGI request. If you do not want to query, you do not need to define this environment variable.
REQUEST_METHOD Provides the method by which the script was called. For scripts using the HTTP/1.0 protocol, only GET and POST are meaningful.
SCRIPT_FILENAME Full path of the CGI script
SCRIPT_NAME Name of the CGI script
SERVER_NAME This is the hostname, alias, or IP address of your web server.
SERVER_SOFTWARE The value of this environment variable contains the name and version number of the HTTP server calling the CGI program. For example, the value above is Apache/2.2.14 (Unix)

Here is a simple CGI script that outputs CGI environment variables:

Example

#!/usr/bin/perl
print "Content-type: text/htmlnn";
print '<meta charset="utf-8">';
print "<font size=+1>Environment Variables:</font>n";
foreach (sort keys %ENV) {
    print "<b>$_</b>: $ENV{$_}<br>n";
}
1;

File Download

If we want to implement file download through Perl CGI, we need to set different header information, as shown below:

Example

#!/usr/bin/perl
print "Content-Type:application/octet-stream; name="FileName"rn";
print "Content-Disposition: attachment; filename="FileName"rnn";
open(FILE, "<FileName");
while(read(FILE, $buffer, 100)) {
    print("$buffer");
}

Using GET Method to Transmit Data

The GET method sends encoded user information to the server. The data information is included in the URL of the requested page, separated by a "?", as shown below:

http://www.test.com/cgi-bin/test.cgi?key1=value1&key2=value2

Some other notes about GET requests:

  • GET requests can be cached
  • GET requests remain in browser history
  • GET requests can be bookmarked
  • GET requests should not be used when processing sensitive data
  • GET requests have length limitations
  • GET requests should only be used to retrieve data

Simple URL Example: GET Method

Here is a simple URL that uses the GET method to send two parameters to the test.cgi program:

/cgi-bin/test.cgi?name=Tutorial%20Tutorial&url=

The code for the test.cgi file is as follows:

Example

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "GET") {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
$name = $FORM{name};
$url = $FORM{url};
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2>$name URL: $url</h2>";
print "</body>";
print "</html>";
1;

Viewing in the browser, the output is as follows:

Image 3

Simple Form Example: GET Method

Here is an HTML form that uses the GET method to send two pieces of data to the server. The submitted server script is also the test.cgi file. The test.html code is as follows:

test.html File Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="get">
    Site Name: <input type="text" name="name"><br/>
    Site URL: <input type="text" name="url"/>
    <input type="submit" value="Submit"/>
</form>
</body>
</html>

In the browser, the execution effect is as follows:

Image 4


Using POST Method to Transmit Data

Using the POST method to transmit data to the server is more secure and reliable. Sensitive information such as user passwords requires the use of the POST method for data transmission.

Below is also test.cgi, which can also handle POST form data submitted by the browser:

test.cgi Code

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
$name = $FORM{name};
$url = $FORM{url};
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2>$name URL: $url</h2>";
print "</body>";
print "</html>";
1;

Here is an HTML form that uses the GET method to send two pieces of data to the server. The submitted server script is also the test.cgi file. The test.html code is as follows:

test.html Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post">
    Site Name: <input type="text" name="name"><br/>
    Site URL: <input type="text" name="url"/>
    <input type="submit" value="Submit"/>
</form>
</body>
</html>

In the browser, the execution effect is as follows:

Image 5

Passing Checkbox Data via CGI Program

Checkbox is used to submit one or more option data. The test.html code is as follows:

test.html Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="POST" target="_blank">
    <input type="checkbox" name="tutorial" value="on"/> 
    <input type="checkbox" name="google" value="on"/> Google
    <input type="submit" value="Select Site"/>
</form>
</body>
</html>

The code for the test.cgi file is as follows:

test.cgi Code

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
if ($FORM{tutorial}) {
    $tutorial_flag = "ON";
} else {
    $tutorial_flag = "OFF";
}
if ($FORM{google}) {
    $google_flag = "ON";
} else {
    $google_flag = "OFF";
}
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2>  Selection Status: $tutorial_flag</h2>";
print "<h2> Google Selection Status: $google_flag</h2>";
print "</body>";
print "</html>";
1;

In the browser, the execution effect is as follows:

Image 6


Passing Radio Data via CGI Program

Radio only transmits one piece of data to the server. The test.html code is as follows:

test.html Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post" target="_blank">
    <input type="radio" name="site" value="tutorial"/> 
    <input type="radio" name="site" value="google"/> Google
    <input type="submit" value="Submit"/>
</form>
</body>
</html>

The test.cgi script code is as follows:

test.cgi Code

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
$site = $FORM{site};
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2> Selected Site: $site</h2>";
print "</body>";
print "</html>";
1;

In the browser, the execution effect is as follows:

Image 7


Passing Textarea Data via CGI Program

Textarea transmits multi-line data to the server. The test.html code is as follows:

test.html Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post" target="_blank">
    <textarea name="textcontent" cols="40" rows="4">
        Enter content here...
    </textarea>
    <input type="submit" value="Submit"/>
</form>
</body>
</html>

The test.cgi script code is as follows:

test.cgi Code

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
$text_content = $FORM{textcontent};
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2>Entered Text Content: $text_content</h2>";
print "</body>";
print "</html>";
1;

In the browser, the execution effect is as follows:

Image 8


Passing Dropdown Data via CGI Program

HTML dropdown box code is as follows:

test.html Code

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>()</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post" target="_blank">
    <select name="dropdown">
        <option value="tutorial" selected></option>
        <option value="google">Google</option>
    </select>
    <input type="submit" value="Submit"/>
</form>
</body>
</html>

The test.cgi script code is as follows:

test.cgi Code

#!/usr/bin/perl
local($buffer, @pairs, $pair, $name, $value, %FORM);
$ENV{'REQUEST_METHOD'} =~ tr/a-z/A-Z/;
if ($ENV{'REQUEST_METHOD'} eq "POST") {
    read(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
} else {
    $buffer = $ENV{'QUERY_STRING'};
}
@pairs = split(/&/, $buffer);
foreach $pair (@pairs) {
    ($name, $value) = split(/=/, $pair);
    $value =~ tr/+/ /;
    $value =~ s/%(..)/pack("C", hex($1))/eg;
    $FORM{$name} = $value;
}
$site = $FORM{dropdown};
print "Content-type:text/htmlrnrn";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>()</title>';
print "</head>";
print "<body>";
print "<h2>Selected Site: $site</h2>";
print "</body>";
print "</html>";
1;

In the browser, the execution effect is as follows:

Image 9


Using Cookies in CGI

A major drawback of the HTTP protocol is that it does not judge user identity, which brings great inconvenience to programmers. The appearance of cookie functionality makes up for this deficiency.

A cookie is a record of data written to the client's hard disk through the client's browser while the client is accessing the script. The next time the client accesses the script, the data information is retrieved, thereby achieving the function of identity verification. Cookies are commonly used in identity verification.

Cookie Syntax

HTTP cookies are sent via HTTP headers, which occur before the file transfer. The syntax for the set-cookie header is as follows:

Set-cookie:name=name;expires=date;path=path;domain=domain;secure
  • name=name: The value of the cookie to be set (name cannot use ";" and "," characters). When there are multiple name values, separate them with ";", for example: name1=name1;name2=name2;name3=name3.
  • expires=date: The expiration date of the cookie. Format: expires="Wdy,DD-Mon-YYYY HH:MM:SS"
  • path=path: Sets the path supported by the cookie. If path is a path, the cookie is valid for that path and its subdirectories.
  • domain=domain: Specifies the domain for which the cookie is valid.
  • secure: If this attribute is present, the cookie is only sent over secure HTTPS connections.
← Perl Process ManagementPerl Database Access β†’