## Python3.x Python CGI Programming
* * *
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, providing an interface to communicate with client HTML pages.
* * *
## Web Browsing
To better understand how CGI works, we can follow 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, the web server parses the URL and checks if the requested file exists on the server. If it exists, the file content is returned; if not, an error message is returned.
* 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 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 execute CGI programs stored 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 Python can also use the .py extension.
By default, the Linux server is configured to run the cgi-bin directory at /var/www.
If you want to specify another directory for running CGI scripts, you can modify the httpd.conf configuration file as follows:
AllowOverride None Options +ExecCGI Order allow,deny Allow from all
Add the .py suffix in AddHandler, so we can access Python script files ending with .py:
AddHandler cgi-script .cgi .pl .py
* * *
## First CGI Program
We use Python to create the first CGI program. The file is named hello.py, located in the /var/www/cgi-bin directory, with the following content:
## Example
#!/usr/bin/python3
print("Content-type:text/html")
print()# Empty line, telling the server to end the header
print('')
print('')
print('')
print('
Hello Word - My First CGI Program!')
print('')
print('')
print('
Hello Word! I am the first CGI program from
')
print('')
print('')
After saving the file, modify hello.py and change the file permissions to 755:
chmod 755 hello.py
The above program displays the following result when accessed in a browser:
!(#)
This hello.py script is a simple Python script. The first line of the script outputs "Content-type:text/html" to the browser, informing the browser that the content type to display is "text/html".
Using print to output an empty line tells the server to end the header information.
* * *
## HTTP Headers
The "Content-type:text/html" in the hello.py file is part of the HTTP header, which is sent to the browser to inform it of 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/html
The following table introduces commonly used information in HTTP headers for CGI programs:
| Header | Description |
| --- | --- |
| Content-type: | The MIME information corresponding to the requested entity. For example: Content-type:text/html |
| Expires: Date | The 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 | The last modification time of the requested resource |
| Content-length: N | The content length of the request |
| Set-Cookie: String | Sets an 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 communicates with the CGI program via POST, this environment variable indicates the number of valid data bytes that can be read from standard input (STDIN). This variable must be used when reading input data. |
| HTTP_COOKIE | The content of the COOKIE in the client. |
| HTTP_USER_AGENT | Provides client browser information including version numbers or other proprietary data. |
| PATH_INFO | The value of this environment variable indicates 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 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 this, this environment variable does not need to be defined. |
| 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 | The full path of the 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 calling 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/python3
import os
print("Content-type: text/html")
print()
print("")
print("
Environment Variables")
print("
")
for key in os.environ.keys():
print("- %30s : %s
" % (key,os.environ))
print("
")
Save the above as test.py, modify the file permissions to 755, and the execution result is as follows:
!(#)
* * *
## GET and POST Methods
Browser clients transmit information to the server through two methods: the GET method and the POST method.
### Using the 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 request page, separated by a "?", as shown below:
http://www.test.com/cgi-bin/hello.py?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
The following is a simple URL that uses the GET method to send two parameters to the hello_get.py program:
/cgi-bin/hello_get.py?name=&url=
The following is the code for the hello_get.py file:
## Example
#!/usr/bin/python3
# CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Get data
site_name = form.getvalue('name')
site_url = form.getvalue('url')
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
%s Official Website: %s
" % (site_name, site_url))
print("")
print("")
After saving the file, modify hello_get.py and change the file permissions to 755:
chmod 755 hello_get.py
Browser request output result:
!(#)
### Simple Form Example: GET Method
The following 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 hello_get.py file. The hello_get.html code is as follows:
## Example
Site Name:
Site URL:
By default, the cgi-bin directory can only store script files. We store hello_get.html in the test directory and change the file permissions to 755:
chmod 755 hello_get.html
The GIF demonstration is as follows:
!(#)
### Using the 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 POST for data transmission.
The following is also hello_get.py, which can also handle POST form data submitted by the browser:
## Example
#!/usr/bin/python3
# CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Get data
site_name = form.getvalue('name')
site_url = form.getvalue('url')
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
%s Official Website: %s
" % (site_name, site_url))
print("")
print("")
The following form submits data to the server script hello_get.py via the POST method (**method="post**"):
## Example
Site Name:
Site URL:
The GIF demonstration is as follows:
!(#)
### Passing Checkbox Data via CGI Program
Checkbox is used to submit one or more option data. The HTML code is as follows:
## Example
Google
The following is the code for the checkbox.py file:
## Example
#!/usr/bin/python3
# Import CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Receive field data
if form.getvalue('google'):
google_flag ="Yes"
else:
google_flag ="No"
if form.getvalue('tutorial'):
tutorial_flag ="Yes"
else:
tutorial_flag ="No"
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
selected: %s
" % tutorial_flag)
print("
Google selected: %s
" % google_flag)
print("")
print("")
Modify checkbox.py permissions:
chmod 755 checkbox.py
Browser access GIF demonstration:
!(#)
### Passing Radio Data via CGI Program
Radio only transmits one piece of data to the server. The HTML code is as follows:
## Example
Google
The radiobutton.py script code is as follows:
## Example
#!/usr/bin/python3
# Import CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Receive field data
if form.getvalue('site'):
site= form.getvalue('site')
else:
site="Submitted data is empty"
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
The selected website is %s
" % site)
print("")
print("")
Modify radiobutton.py permissions:
chmod 755 radiobutton.py
Browser access GIF demonstration:
!(#)
### Passing Textarea Data via CGI Program
Textarea transmits multi-line data to the server. The HTML code is as follows:
## Example
The textarea.py script code is as follows:
## Example
#!/usr/bin/python3
# Import CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Receive field data
if form.getvalue('textcontent'):
text_content = form.getvalue('textcontent')
else:
text_content ="No content"
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
The entered content is: %s
" % text_content)
print("")
print("")
>
Modify textarea.py permissions:
chmod 755 textarea.py
Browser access GIF demonstration:
!(#)
### Passing Dropdown Data via CGI Program.
The HTML dropdown code is as follows:
## Example
Google
The dropdown.py script code is as follows:
## Example
#!/usr/bin/python3
# Import CGI processing module
import cgi,cgitb
# Create an instance of FieldStorage
form =cgi.FieldStorage()
# Receive field data
if form.getvalue('dropdown'):
dropdown_value = form.getvalue('dropdown')
else:
dropdown_value ="No content"
print("Content-type:text/html")
print()
print("")
print("")
print("")
print("
CGI Test Example")
print("")
print("")
print("
The selected option is: %s
" % dropdown_value)
print("")
print("")
Modify dropdown.py permissions:
chmod 755 dropdown.py
Browser access GIF demonstration:
!(#)
* * *
## Using Cookies in CGI
A major drawback of the HTTP protocol is that it does not identify user identity, which brings great inconvenience to programmers. The appearance of cookie functionality compensates for this deficiency.
A cookie is a record of data written to the client's hard drive through the client's browser while the client is accessing a script. The data information is retrieved the next time the client accesses the script, thereby achieving identity verification. Cookies are commonly used in identity verification.
### Cookie Syntax
The sending of HTTP cookies is achieved through HTTP headers, which occurs 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 "**,**"). When there are multiple name values, they are separated by "**;**", 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 directory, the cookie applies to all files and subdirectories under that directory, for example: path="/cgi-bin/". If path is a file, the cookie applies only to that file, for example: path="/cgi-bin/cookie.cgi".
* **domain=domain:** The domain for which the cookie is effective, for example: domain="www."
* **secure:** If this flag is provided, it indicates that the cookie can only be transmitted via HTTPS servers using the SSL protocol.
* The receiving of cookies is achieved by setting the environment variable HTTP_COOKIE. CGI programs can retrieve cookie information by searching this variable.
* * *
## Cookie Setting
Setting cookies is very simple. Cookies are sent separately in the HTTP header. The following example sets name and expires in the cookie:
## Example
#!/usr/bin/python3
print('Set-Cookie: name="";expires=Wed, 28 Aug 2016 18:30:00 GMT')
print('Content-Type: text/html')
print()
print("""
Cookie set OK!