What is CGI
CGI is currently maintained by NCSA, which defines CGI as follows:
CGI (Common Gateway Interface), Common Gateway Interface, is a program that runs on a server such as an HTTP server and provides an interface with the client's HTML page.
web browsing
To better understand how CGI works, we can start with the process of clicking a link or URL on a web page:
1. Use your browser to access the URL and connect to the HTTP web server.
2. After receiving the request information, the web server will parse the URL and check whether the accessed file exists on the server. If the file exists, it will return the content of the file, otherwise it will return an error message.
3. The browser receives 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
Web server support and configuration
Before you perform CGI programming, make sure your web server supports CGI and has configured a CGI handler.
Apache supports CGI configuration:
Set up the CGI directory:
ScriptAlias /cgi-bin/ /var/www/cgi-bin/
All HTTP server execution CGI programs are saved 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 a .cgi extension, and Perl can also use a .pl extension.
By default, the Linux server configuration runs in the cgi-bin directory in /var/www.
If you want to specify another 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 the .pl suffix to AddHandler so that we can access Perl script files ending in .pl:
AddHandler cgi-script .cgi .pl .py
The first CGI program
Below we create a test.cgi file, the code is as follows:
test.cgi code
#!/usr/bin/perl print " Content-type:text/html r n r n " ; print ' <html> ' ; print ' <head> ' ; print ' <meta charset="utf-8"> ' ; print ' <title>Coder Tutorial (codercto.com)</title> ' ; print ' </head> ' ; print ' <body> ' ; print ' <h2>Hello Word! </h2> ' ; print ' <p>The first CGI program from the Programmer's Tutorial. </p> ' ; print ' </body> ' ; print ' </html> ' ; 1 ; Then open http://localhost/cgi-bin/test.cgi through the browser, the output results are as follows:
The output content of the first line of the script "Content-type: text/htmlrnrn" is sent to the browser and tells the browser that the displayed content type is "text/html".
HTTP header
The "Content-type:text/html" in the content of the test.cgi file is part of the HTTP header, which is sent to the browser to tell the browser 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 information commonly used in HTTP headers in CGI programs:
head | describe |
---|
Content-type: | The requested MIME information corresponding to the entity. For example: Content-type:text/html |
Expires: Date | Response expiration date and time |
Location: URL | Used to redirect the recipient to the location of a non-requested URL to complete the request or identify a new resource. |
Last-modified: Date | The last modification time of the requested resource |
Content-length: N | Requested content length |
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 | describe |
---|
CONTENT_TYPE | The value of this environment variable indicates the MIME type of the information being passed. Currently, the environment variable CONTENT_TYPE is generally: application/x-www-form-urlencoded, which indicates that the data comes from HTML forms. |
CONTENT_LENGTH | If the information transfer method between the server and the CGI program is POST, this environment variable is the number of bytes of valid data that can be read from the standard input STDIN. This environment variable must be used when reading the entered data. |
HTTP_COOKIE | COOKIE content in the client. |
HTTP_USER_AGENT | Provide customer browser information including version numbers 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 to CGI programs. |
QUERY_STRING | If the information transfer method between the server and the CGI program is GET, the value of this environment variable is the information transferred. 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 is always present. And it is the unique identifier that the Web client needs to provide to the Web server, which can be used in CGI programs to distinguish different Web clients. |
REMOTE_HOST | The value of this environment variable contains the host name of the client that sent the CGI request. If the query you want to query is not supported, there is no need to define this environment variable. |
REQUEST_METHOD | Provides the method by which the script is called. For scripts using the HTTP/1.0 protocol, only GET and POST are meaningful. |
SCRIPT_FILENAME | Full path to CGI script |
SCRIPT_NAME | The 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 that calls the CGI program. For example, the value above is Apache/2.2.14(Unix) |
The following is a simple CGI script that outputs CGI environment variables:
Example
#!/usr/bin/perl print " Content-type: text/html n n " ; print ' <meta charset="utf-8"> ' ; print " <font size=+1>Environment variable:</font> n " ; foreach ( sort keys %ENV ) { print " <b> $_ </b>: $ENV { $_ }<br> n " ; } 1 ; File download
If we want to download files through Perl CGI, we need to set different header information, as shown below:
Example
#!/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 " ) ; } Transfer data using GET method
The GET method sends the encoded user information to the server. The data information is included in the URL of the requested page, separated by "?", as shown below:
http://www.test.com/cgi-bin/test.cgi?key1=value1&key2=value2
Some additional 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 handling sensitive data
GET requests have length limits
GET requests should only be used to retrieve data
Simple url example: GET method
The following is a simple URL that uses the GET method to send two parameters to the test.cgi program:
/cgi-bin/test.cgi?name=Coder Tutorial&url=http://www.codercto.com
The following is the code of the test.cgi file:
Example
#!/usr/bin/perl local ( $buffer , @pairs , $pair , $name , $value , %FORM ) ; # Read text information $ENV { ' REQUEST_METHOD ' } =~ tr / a - z / A - Z /; if ( $ENV { ' REQUEST_METHOD ' } eq " GET " ) { $buffer = $ENV { ' QUERY_STRING ' } ; } # Read name/value pair information @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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2> $name URL: $url </h2> " ; print " </body> " ; print " </html> " ; 1 ; Check the browser and the output is as follows:
Simple form example: GET method
The following is an HTML form that uses the GET method to send two 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> Coder Tutorial ( codercto.com ) </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:
Pass data using POST method
It is more secure and reliable to use the POST method to transmit data to the server. Some sensitive information such as user passwords need to use POST to transmit data.
The following 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 ) ; # Read text information $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 ' } ; } # Read name/value pair information @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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2> $name URL: $url </h2> " ; print " </body> " ; print " </html> " ; 1 ; The following is an HTML form that uses the GET method to send two 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> Coder Tutorial ( codercto.com ) </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:
Pass checkbox data through 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> Coder Tutorial ( codercto.com ) </title> </ head > <body> < form action = " /cgi-bin/test.cgi " method = " POST " target = " _blank " > < input type = " checkbox " name = " codercto " value = " on " /> Coder Tutorial < input type = " checkbox " name = " google " value = " on " /> Google < input type = " submit " value = " Select site " /> </form> </body> </html> The following is the code of the test.cgi file:
test.cgi code
#!/usr/bin/perl local ( $buffer , @pairs , $pair , $name , $value , %FORM ) ; # Read information $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 ' } ; } # Read name/value pair information @pairs = split ( /&/, $buffer ) ; foreach $pair ( @pairs ) { ( $name , $value ) = split ( /=/, $pair ) ; $value =~ tr /+/ / ; $value =~ s / % ( .. ) / pack ( " C " , hex ( $1 ) ) / eg ; $FORM { $name } = $value ; } if ( $FORM { codercto } ) { $codercto_flag = " ON " ; } else { $codercto_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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2> Coder Tutorial selected status: $codercto_flag </h2> " ; print " <h2> Google selection status: $google_flag </h2> " ; print " </body> " ; print " </html> " ; 1 ; In the browser, the execution effect is as follows:
Pass Radio data through CGI program
Radio only passes one data to the server. The test.html code is as follows:
test.html code
< ! DOCTYPE html > <html> <head> < meta charset = " utf-8 " > <title> Coder Tutorial ( codercto.com ) </title> </ head > <body> < form action = " /cgi-bin/test.cgi " method = " post " target = " _blank " > < input type = " radio " name = " site " value = " codercto " /> Coder 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 ) ; # Read information $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 ' } ; } # Read name/value pair information @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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2> Selected website $site </h2> " ; print " </body> " ; print " </html> " ; 1 ; In the browser, the execution effect is as follows:
Pass Textarea data through CGI program
Textarea transmits multiple lines of data to the server. The test.html code is as follows:
test.html code
< ! DOCTYPE html > <html> <head> < meta charset = " utf-8 " > <title> Coder Tutorial ( codercto.com ) </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 ) ; # Read information $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 ' } ; } # Read name/value pair information @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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2>The input text content is: $text_content </h2> " ; print " </body> " ; print " </html> " ; 1 ; In the browser, the execution effect is as follows:
Pass drop-down data through CGI program
The HTML drop-down box code is as follows:
test.html code
< ! DOCTYPE html > <html> <head> < meta charset = " utf-8 " > <title> Coder Tutorial ( codercto.com ) </title> </ head > <body> < form action = " /cgi-bin/test.cgi " method = " post " target = " _blank " > < select name = " dropdown " > < option value = " codercto " selected > Coder Tutorial </ 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 ) ; # Read information $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 ' } ; } # Read name/value pair information @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>Coder Tutorial (codercto.com)</title> ' ; print " </head> " ; print " <body> " ; print " <h2>The selected website is: $site </h2> " ; print " </body> " ; print " </html> " ; 1 ; In the browser, the execution effect is as follows:
Use of cookies in CGI
A big shortcoming of the http protocol is that it does not judge the user's identity, which brings great inconvenience to programmers. The emergence of the cookie function makes up for this shortcoming.
Cookies write record data on the customer's hard drive through the customer's browser when the customer accesses the script. The data information is retrieved the next time the customer accesses the script, thereby achieving the function of identity discrimination. Cookies are often used in identity verification.
Cookie syntax
The sending of http cookies is implemented through http headers, which are earlier than the transfer of files. The syntax of the set-cookie header is as follows:
Set-cookie:name=name;expires=date;path=path;domain=domain;secure
name=name: The cookie value needs to be set (name cannot use " ; " and " , "). Use " ; " to separate multiple name values, for example: name1=name1;name2=name2;name3=name3 .
expires=date: cookie validity period, format: expires="Wdy,DD-Mon-YYYY HH:MM:SS"
path=path: Set the path supported by cookies. If path is a path, the cookie will take effect on all files and subdirectories in this directory. For example: path="/cgi-bin/". If path is a file, the cookie will be effective. Refers to take effect on this file, for example: path="/cgi-bin/cookie.cgi".
domain=domain: The domain name that is effective for cookies, for example: domain="www.codercto.com"
secure: If this flag is given, it means that the cookie can only be passed through an https server with SSL protocol.
Receiving cookies is achieved by setting the environment variable HTTP_COOKIE. CGI programs can obtain cookie information by retrieving this variable.
Cookie settings
Cookie setting is very simple, the cookie will be sent separately in the http header. The following example sets UserID, Password, and expires in cookies:
Example
#!/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 . codercto . com ; n " ;print " Set - Cookie : Path =/ perl ; n " ;print " Content - type : text / html r n r n " ;.......Other HTML content Find Cookies
The cookie information retrieval page is very simple. Cookie information is stored in the CGI environment variable HTTP_COOKIE. The storage format is as follows:
Example
#!/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 output result of the above example is:
User ID = XYZPassword = XYZ123
CGI module
Perl provides many built-in CGI modules, the following two are commonly used:
CGI module
Berkeley cgi-lib.pl