Latest web development tutorials

Perl CGI Programming

What is CGI

CGI currently maintained by NCSA, NCSA CGI is defined as follows:

CGI (Common Gateway Interface), Common Gateway Interface, which is a program running on the server, such as: HTTP server, the client interface providing the same HTML page.


Web browsing

To better understand how CGI works, we can click on a link on a web page or URL of the process:

  • 1, use your browser to access the URL and connect to the HTTP web server.
  • 2, Web server receives the request message will be parsed URL and look accessed files on the server if there is, if there is to return the contents of the file, otherwise it returns an error message.
  • 3, the browser receives the information from the server and displays the received file or error messages.

CGI programs can be a Python script, PERL script, SHELL script, C or C ++ programs.


CGI Chart

cgiarch


Web server configuration and support

Before you conduct CGI programming, make sure that your Web server has been configured to support CGI and CGI handler.

Apache supports CGI configuration:

Set up the CGI directory:

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

All HTTP server to execute CGI programs are stored in a pre-configured directory. This directory is called the CGI directory, and by convention, it is named / var / www / cgi-bin directory.

CGI file extension .cgi, Perl can also use the .pl extension.

By default, Linux server configuration running cgi-bin directory is / var / www.

If you want to specify a different directory to run CGI scripts, you can modify the httpd.conf configuration file as follows:

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

Add suffix .pl AddHandler, so we can access the end of the .pl Perl script file:

AddHandler cgi-script .cgi .pl .py

The first CGI program

Below we create a test.cgi file, the code is as follows:

#!/usr/bin/perl

print "Content-type:text/html\r\n\r\n";
print '<html>';
print '<head>';
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print '</head>';
print '<body>';
print '<h2>Hello Word! </h2>';
print '<p>来自本教程第一个 CGI 程序。</p>';
print '</body>';
print '</html>';

1;

Then open your browser to http: //localhost/cgi-bin/test.cgi, output results are as follows:

The output of the first line of the script "Content-type: text / html \ r \ n \ r \ n" is sent to the browser and tell the browser to display the content type "text / html".


HTTP header

test.cgi file contents in: part of the HTTP header is "Content-type text / html", it will be sent to the browser content type tells the browser files.

HTTP header format is as follows:

HTTP 字段名: 字段内容

E.g:

Content-type:text/html\r\n\r\n

The following table describes the information in the HTTP header CGI programs are often used:

head description
Content-type: MIME entity corresponding to the information request. For example: Content-type: text / html
Expires: Date Response date and time expired
Location: URL To redirect the recipient to a non-location URL request to complete the request or identification of new resources
Last-modified: Date Requested resource was last modified
Content-length: N Content-Length request
Set-Cookie: String Http Cookie settings

CGI Environment Variables

All CGI programs have received the following environment variables, which played an important role in the CGI program:

variable name description
CONTENT_TYPE This value indicates that the environment variable to the MIME type of information transfer. At present, the environment variables are generally CONTENT_TYPE: application / x-www-form-urlencoded, he said that the data from the HTML form.
CONTENT_LENGTH If the transfer mode server and CGI program information is POST, even if the environment variable STDIN input the number of bytes that can be read valid data from the standard. This environment variable when reading the input data must be used.
HTTP_COOKIE COOKIE content within the client.
HTTP_USER_AGENT Providing information includes the version number of the client browser or other proprietary data.
PATH_INFO The value of this environment variable indicates the name of the CGI program immediately after the additional path information. It often appears as an argument CGI program.
QUERY_STRING If the transfer mode server and CGI program information is information GET, the value of this environment variable even if passed. This information is followed by the name of the CGI program, both in the middle with a question mark '?' Separator.
REMOTE_ADDR The value of this environment variable is the IP address of the client sends a request, for example, the above 192.168.1.67. This value is always present. And it is the need to provide the Web client to the Web server's unique identifier can be used in CGI programs to distinguish between different Web client.
REMOTE_HOST The value of this environment variable contains the host name of the requesting client of CGI. If it does not you want to check, you do not need to define this environment variable.
REQUEST_METHOD It provides a method called script. For HTTP / 1.0 protocol script only GET and POST meaningful.
SCRIPT_FILENAME The full path to CGI scripts
SCRIPT_NAME The name of the CGI script
SERVER_NAME This is the host name, alias, or IP address of your WEB server.
SERVER_SOFTWARE The value of this environment variable contains the call CGI program name and version number of the HTTP server. For example, the above value of Apache / 2.2.14 (Unix)

Here is a simple CGI script output CGI environment variables:

#!/usr/bin/perl

print "Content-type: text/html\n\n";
print '<meta charset="utf-8">';
print "<font size=+1>环境变量:</font>\n";
foreach (sort keys %ENV)
{
  print "<b>$_</b>: $ENV{$_}<br>\n";
}

1;

Download Document

If we want to achieve through Perl CGI file downloads, require a different set of header information as follows:

#!/usr/bin/perl

# HTTP Header
print "Content-Type:application/octet-stream; name=\"FileName\"\r\n";
print "Content-Disposition: attachment; filename=\"FileName\"\r\n\n";

# Actual File Content will go hear.
open( FILE, "<FileName" );
while(read(FILE, $buffer, 100) )
{
   print("$buffer");
}

Use the GET method of transferring data

GET method to send the encoded user information to the server, the data information is contained in the URL of the page request to number divided as follows "?":

http://www.test.com/cgi-bin/test.cgi?key1=value1&key2=value2
GET requests about some of the other comments:
  • GET request can be cached
  • GET request remains in the browser history
  • GET requests can be bookmarked
  • GET requests should not be used when dealing with sensitive data
  • GET requests have length restrictions
  • GET requests should only be used to retrieve data

Examples of simple url: GET method

The following is a simple URL, using GET method to send two parameters to test.cgi program:

/cgi-bin/test.cgi?name=本教程&url=http://www.w3big.com

A code test.cgi file:

#!/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'};
}
# 读取 name/value 对信息
@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/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2>$name网址:$url</h2>";
print "</body>";
print "</html>";

1;

Check your browser, the output results are as follows:

Examples of simple form: GET method

The following is a two send data to the server using the GET method via an HTML form, submitted the same server script test.cgi document, test.html code is as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="get">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>

Browser implementation of the results is as follows:


Use the POST method to pass data

Using the POST method to pass data to the server is more secure and reliable, as some sensitive information such as user passwords need to use POST to transfer data.

The following is also test.cgi, it can also handle POST form data submitted by the browser:

#!/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'};
}
# 读取 name/value 对信息
@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/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2>$name网址:$url</h2>";
print "</body>";
print "</html>";

1;

The following is a two send data to the server using the GET method via an HTML form, submitted the same server script test.cgi document, test.html code is as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post">
站点名称: <input type="text" name="name">  <br />

站点 URL: <input type="text" name="url" />
<input type="submit" value="提交" />
</form>
</body>
</html>

Browser implementation of the results is as follows:

CGI program to pass data through the checkbox

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

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="POST" target="_blank">
<input type="checkbox" name="w3big" value="on" /> 本教程
<input type="checkbox" name="google" value="on" /> Google
<input type="submit" value="选择站点" />
</form>
</body>
</html>

A code test.cgi file:

#!/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'};
}
# 读取 name/value 对信息
@pairs = split(/&/, $buffer);
foreach $pair (@pairs)
{
   ($name, $value) = split(/=/, $pair);
   $value =~ tr/+/ /;
   $value =~ s/%(..)/pack("C", hex($1))/eg;
   $FORM{$name} = $value;
}
if( $FORM{w3big} ){
   $w3big_flag ="ON";
}else{
   $w3big_flag ="OFF";
}
if( $FORM{google} ){
   $google_flag ="ON";
}else{
   $google_flag ="OFF";
}

print "Content-type:text/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2> 本教程选中状态 : $w3big_flag</h2>";
print "<h2> Google 选择状态 : $google_flag</h2>";
print "</body>";
print "</html>";

1;

Browser implementation of the results is as follows:


Radio data transfer via CGI program

Radio only transfer data to a server, test.html code is as follows:

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

test.cgi script code is as follows:

#!/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'};
}
# 读取 name/value 对信息
@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/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2> 选择的网站 $site</h2>";
print "</body>";
print "</html>";

1;

Browser implementation of the results is as follows:


Textarea transfer data via CGI program

Textarea pass multiple rows of data to the server, test.html code is as follows:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>本教程(w3big.com)</title>
</head>
<body>
<form action="/cgi-bin/test.cgi" method="post" target="_blank">
<textarea name="textcontent" cols="40" rows="4">
在这里输入内容...
</textarea>
<input type="submit" value="提交" />
</form>
</body>
</html>

test.cgi script code is as follows:

#!/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'};
}
# 读取 name/value 对信息
@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/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2>输入的文本内容为:$text_content</h2>";
print "</body>";
print "</html>";

1;

Browser implementation of the results is as follows:


CGI program to pass data through the pull-down

HTML drop-down box code as follows:

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

test.cgi script code as follows:

#!/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'};
}
# 读取 name/value 对信息
@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/html\r\n\r\n";
print "<html>";
print "<head>";
print '<meta charset="utf-8">';
print '<title>本教程(w3big.com)</title>';
print "</head>";
print "<body>";
print "<h2>选择的网站是:$site</h2>";
print "</body>";
print "</html>";

1;

Browser implementation of the results is as follows:


CGI is used Cookie

Http protocol in a big drawback is wrong to judge a user's identity, which give programmers a great deal of inconvenience, but appears cookie functionality made up for this deficiency.

cookie that is accessing the script while the customer through the customer's browser on the client hard disk to write data records, retrieve data when a customer visits the next script, so as to achieve the function of determining the identity, cookie commonly used in verifying identity.

cookie syntax

Http cookie is sent through the http header to achieve, he had to transfer files, header set-cookie syntax is as follows:

Set-cookie:name=name;expires=date;path=path;domain=domain;secure 
  • name = name: to set the value of the cookie (name can not be used ";" and "," number), when there are multiple name values ";" to separate, for example: name1 = name1; name2 = name2 ; name3 = name3.
  • expires = date: cookie expiration date in the format: expires = "Wdy, DD- Mon-YYYY HH: MM: SS"
  • path = path: the path set cookie support, if the path is a path, the cookie for all files and subdirectories of the directory entry into force, for example: path = "/ cgi-bin /", if the path is a file, cookie It refers to the entry into force of this file, for example: path = "/ cgi-bin / cookie.cgi".
  • domain = domain: the domain name of the cookie is valid, for example: domain = "www.w3big.com"
  • secure: If this flag is given, that the cookie can only be transmitted through SSL protocol https server.
  • cookie is received by setting environment variables HTTP_COOKIE achieved, CGI programs can obtain information by retrieving the cookie variable.

Cookie settings

Cookie settings is very simple, cookie will be sent separately at http header. The following example sets the UserID, Password and expires in a cookie:

#!/usr/bin/perl

print "Set-Cookie:UserID=XYZ;\n";
print "Set-Cookie:Password=XYZ123;\n";
print "Set-Cookie:Expires=Tuesday, 31-Dec-2017 23:12:40 GMT";\n";
print "Set-Cookie:Domain=www.w3big.com;\n";
print "Set-Cookie:Path=/perl;\n";
print "Content-type:text/html\r\n\r\n";
...........其他 HTML 内容

Find Cookie

Cookie information retrieval page is very simple, in the CGI environment variables HTTP_COOKIE, the storage format is as follows Cookie information is stored:

#!/usr/bin/perl
$rcvd_cookies = $ENV{'HTTP_COOKIE'};
@cookies = split /;/, $rcvd_cookies;
foreach $cookie ( @cookies ){
   ($key, $val) = split(/=/, $cookie); # splits on the first =.
   $key =~ s/^\s+//;
   $val =~ s/^\s+//;
   $key =~ s/\s+$//;
   $val =~ s/\s+$//;
   if( $key eq "UserID" ){
      $user_id = $val;
   }elsif($key eq "Password"){
      $password = $val;
   }
}
print "User ID  = $user_id\n";
print "Password = $password\n";

The above example output is:

User ID = XYZ
Password = XYZ123

CGI module

Perl CGI provides many built-in module, used the following two: