How to program CGI in python

Follow by Email
Facebook0
Facebook
Google+
https://codingsec.net/2016/05/program-cgi-python/

In this article I will share the basics of the CGI in python.

The Common Gateway Interface, or CGI, is a set of standards that define how information is exchanged between the web server and a custom script. The CGI specs are currently maintained by the NCSA and NCSA.

What is CGI?

  • The Common Gateway Interface, or CGI, is a standard for external gateway programs to interface with information servers such as HTTP servers.
  • The current version is CGI/1.1 and CGI/1.2 is under progress.

Web Browsing

To understand the concept of CGI, let us see what happens when we click a hyper link to browse a particular web page or URL.

  • Your browser contacts the HTTP web server and demands for the URL, i.e., filename.
  • Web Server parses the URL and looks for the filename. If it finds that file then sends it back to the browser, otherwise sends an error message indicating that you requested a wrong file.
  • Web browser takes response from web server and displays either the received file or error message.

However, it is possible to set up the HTTP server so that whenever a file in a certain directory is requested that file is not sent back; instead it is executed as a program, and whatever that program outputs is sent back for your browser to display. This function is called the Common Gateway Interface or CGI and the programs are called CGI scripts. These CGI programs can be a Python Script, PERL Script, Shell Script, C or C++ program, etc.

CGI Architecture Diagram

cgi

Web Server Support and Configuration

Before you proceed with CGI Programming, make sure that your Web Server supports CGI and it is configured to handle CGI Programs. All the CGI Programs to be executed by the HTTP server are kept in a pre-configured directory. This directory is called CGI Directory and by convention it is named as /var/www/cgi-bin. By convention, CGI files have extension as.cgi, but you can keep your files with python extension .py as well.

By default, the Linux server is configured to run only the scripts in the cgi-bin directory in /var/www. If you want to specify any other directory to run your CGI scripts, comment the following lines in the httpd.conf file −

 

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


<Directory "/var/www/cgi-bin">
Options All

Here, we assume that you have Web Server up and running successfully and you are able to run any other CGI program like Perl or Shell, etc.

First CGI Program

This file is kept in /var/www/cgi-bin directory and it has following content. Before running your CGI program, make sure you have change mode of file usingchmod 755 hello.py UNIX command to make file executable.

<span class="com">#!/usr/bin/python</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">'&lt;html&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;head&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;title&gt;Hello Word - First CGI Program&lt;/title&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;/head&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;body&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;h2&gt;Hello Word! This is my first CGI program&lt;/h2&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;/body&gt;'</span>
<span class="kwd">print</span> <span class="str">'&lt;/html&gt;'

</span>

If you click hello.py, then this produces the following output −

Hello Word! This is my first CGI program

This hello.py script is a simple Python script, which writes its output on STDOUT file, i.e., screen. There is one important and extra feature available which is first line to be printed Content-type:text/html\r\n\r\n. This line is sent back to the browser and it specifies the content type to be displayed on the browser screen.

By now you must have understood basic concept of CGI and you can write many complicated CGI programs using Python. This script can interact with any other external system also to exchange information such as RDBMS.

HTTP Header

The line Content-type:text/html\r\n\r\n is part of HTTP header which is sent to the browser to understand the content. All the HTTP header will be in the following form −

<span class="pln">HTTP </span><span class="typ">Field</span> <span class="typ">Name</span><span class="pun">:</span> <span class="typ">Field</span> <span class="typ">Content</span>

<span class="typ">For</span> <span class="typ">Example</span>
<span class="typ">Content</span><span class="pun">-</span><span class="pln">type</span><span class="pun">:</span><span class="pln"> text</span><span class="pun">/</span><span class="pln">html\r\n\r\n</span>

There are few other important HTTP headers, which you will use frequently in your CGI Programming.

Header Description
Content-type: A MIME string defining the format of the file being returned. Example is Content-type:text/html
Expires: Date The date the information becomes invalid. It is used by the browser to decide when a page needs to be refreshed. A valid date string is in the format 01 Jan 1998 12:00:00 GMT.
Location: URL The URL that is returned instead of the URL requested. You can use this field to redirect a request to any file.
Last-modified: Date The date of last modification of the resource.
Content-length: N The length, in bytes, of the data being returned. The browser uses this value to report the estimated download time for a file.
Set-Cookie: String Set the cookie passed through the string

CGI Environment Variables

All the CGI programs have access to the following environment variables. These variables play an important role while writing any CGI program.

Variable Name Description
CONTENT_TYPE The data type of the content. Used when the client is sending attached content to the server. For example, file upload.
CONTENT_LENGTH The length of the query information. It is available only for POST requests.
HTTP_COOKIE Returns the set cookies in the form of key & value pair.
HTTP_USER_AGENT The User-Agent request-header field contains information about the user agent originating the request. It is name of the web browser.
PATH_INFO The path for the CGI script.
QUERY_STRING The URL-encoded information that is sent with GET method request.
REMOTE_ADDR The IP address of the remote host making the request. This is useful logging or for authentication.
REMOTE_HOST The fully qualified name of the host making the request. If this information is not available, then REMOTE_ADDR can be used to get IR address.
REQUEST_METHOD The method used to make the request. The most common methods are GET and POST.
SCRIPT_FILENAME The full path to the CGI script.
SCRIPT_NAME The name of the CGI script.
SERVER_NAME The server’s hostname or IP Address
SERVER_SOFTWARE The name and version of the software the server is running.

Here is small CGI program to list out all the CGI variables. Click this link to see the result Get Environment

<span class="com">#!/usr/bin/python</span>

<span class="kwd">import</span><span class="pln"> os

</span><span class="kwd">print</span> <span class="str">"Content-type: text/html\r\n\r\n"</span><span class="pun">;</span>
<span class="kwd">print</span> <span class="str">"&lt;font size=+1&gt;Environment&lt;/font&gt;&lt;\br&gt;"</span><span class="pun">;</span>
<span class="kwd">for</span><span class="pln"> param </span><span class="kwd">in</span><span class="pln"> os</span><span class="pun">.</span><span class="pln">environ</span><span class="pun">.</span><span class="pln">keys</span><span class="pun">():</span>
  <span class="kwd">print</span> <span class="str">"&lt;b&gt;%20s&lt;/b&gt;: %s&lt;\br&gt;"</span> <span class="pun">%</span> <span class="pun">(</span><span class="pln">param</span><span class="pun">,</span><span class="pln"> os</span><span class="pun">.</span><span class="pln">environ</span><span class="pun">[</span><span class="pln">param</span><span class="pun">])</span>

GET and POST Methods

You must have come across many situations when you need to pass some information from your browser to web server and ultimately to your CGI Program. Most frequently, browser uses two methods two pass this information to web server. These methods are GET Method and POST Method.

Passing Information using GET method

The GET method sends the encoded user information appended to the page request. The page and the encoded information are separated by the ? character as follows −

<span class="pln">http</span><span class="pun">:</span><span class="com">//www.test.com/cgi-bin/hello.py?key1=value1&amp;key2=value2</span>

The GET method is the default method to pass information from browser to web server and it produces a long string that appears in your browser’s Location:box. Never use GET method if you have password or other sensitive information to pass to the server. The GET method has size limtation: only 1024 characters can be sent in a request string. The GET method sends information using QUERY_STRING header and will be accessible in your CGI Program through QUERY_STRING environment variable.

You can pass information by simply concatenating key and value pairs along with any URL or you can use HTML <FORM> tags to pass information using GET method.

Simple URL Example:Get Method

Here is a simple URL, which passes two values to hello_get.py program using GET method.

/cgi-bin/hello_get.py?first_name=ZARA&last_name=ALI

Below is hello_get.py script to handle input given by web browser. We are going to use cgi module, which makes it very easy to access passed information −

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span><span class="pln">
first_name </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'first_name'</span><span class="pun">)</span><span class="pln">
last_name  </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'last_name'</span><span class="pun">)</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Hello - Second CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt;Hello %s %s&lt;/h2&gt;"</span> <span class="pun">%</span> <span class="pun">(</span><span class="pln">first_name</span><span class="pun">,</span><span class="pln"> last_name</span><span class="pun">)</span>
<span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/html&gt;"</span>

This would generate the following result:

Hello ZARA ALI

Simple FORM Example:GET Method

This example passes two values using HTML FORM and submit button. We use same CGI script hello_get.py to handle this input.

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/hello_get.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"get"</span><span class="tag">&gt;</span><span class="pln">
First Name: </span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"first_name"</span><span class="tag">&gt;</span>  <span class="tag">&lt;br</span> <span class="tag">/&gt;</span><span class="pln">

Last Name: </span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"last_name"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Submit"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

Here is the actual output of the above form, you enter First and Last Name and then click submit button to see the result.

First Name:
Last Name:

Passing Information Using POST Method

A generally more reliable method of passing information to a CGI program is the POST method. This packages the information in exactly the same way as GET methods, but instead of sending it as a text string after a ? in the URL it sends it as a separate message. This message comes into the CGI script in the form of the standard input.

Below is same hello_get.py script which handles GET as well as POST method.

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span><span class="pln">
first_name </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'first_name'</span><span class="pun">)</span><span class="pln">
last_name  </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'last_name'</span><span class="pun">)</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Hello - Second CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt;Hello %s %s&lt;/h2&gt;"</span> <span class="pun">%</span> <span class="pun">(</span><span class="pln">first_name</span><span class="pun">,</span><span class="pln"> last_name</span><span class="pun">)</span>
<span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/html&gt;"</span>

Let us take again same example as above which passes two values using HTML FORM and submit button. We use same CGI script hello_get.py to handle this input.

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/hello_get.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"post"</span><span class="tag">&gt;</span><span class="pln">
First Name: </span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"first_name"</span><span class="tag">&gt;&lt;br</span> <span class="tag">/&gt;</span><span class="pln">
Last Name: </span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"text"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"last_name"</span> <span class="tag">/&gt;</span>

<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Submit"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

Here is the actual output of the above form. You enter First and Last Name and then click submit button to see the result.

First Name:
Last Name:

Passing Checkbox Data to CGI Program

Checkboxes are used when more than one option is required to be selected.

Here is example HTML code for a form with two checkboxes −

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/checkbox.cgi"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"POST"</span> <span class="atn">target</span><span class="pun">=</span><span class="atv">"_blank"</span><span class="tag">&gt;</span>
<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"checkbox"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"maths"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"on"</span> <span class="tag">/&gt;</span><span class="pln"> Maths
</span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"checkbox"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"physics"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"on"</span> <span class="tag">/&gt;</span><span class="pln"> Physics
</span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Select Subject"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

The result of this code is the following form:

Maths Physics

Below is checkbox.cgi script to handle input given by web browser for checkbox button.

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span>
<span class="kwd">if</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'maths'</span><span class="pun">):</span><span class="pln">
   math_flag </span><span class="pun">=</span> <span class="str">"ON"</span>
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   math_flag </span><span class="pun">=</span> <span class="str">"OFF"</span>

<span class="kwd">if</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'physics'</span><span class="pun">):</span><span class="pln">
   physics_flag </span><span class="pun">=</span> <span class="str">"ON"</span>
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   physics_flag </span><span class="pun">=</span> <span class="str">"OFF"</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Checkbox - Third CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt; CheckBox Maths is : %s&lt;/h2&gt;"</span> <span class="pun">%</span><span class="pln"> math_flag
</span><span class="kwd">print</span> <span class="str">"&lt;h2&gt; CheckBox Physics is : %s&lt;/h2&gt;"</span> <span class="pun">%</span><span class="pln"> physics_flag
</span><span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/html&gt;"</span>

Passing Radio Button Data to CGI Program

Radio Buttons are used when only one option is required to be selected.

Here is example HTML code for a form with two radio buttons −

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/radiobutton.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"post"</span> <span class="atn">target</span><span class="pun">=</span><span class="atv">"_blank"</span><span class="tag">&gt;</span>
<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"subject"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"maths"</span> <span class="tag">/&gt;</span><span class="pln"> Maths
</span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"radio"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"subject"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"physics"</span> <span class="tag">/&gt;</span><span class="pln"> Physics
</span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Select Subject"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

The result of this code is the following form −

Maths Physics

Below is radiobutton.py script to handle input given by web browser for radio button:

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span>
<span class="kwd">if</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'subject'</span><span class="pun">):</span><span class="pln">
   subject </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'subject'</span><span class="pun">)</span>
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   subject </span><span class="pun">=</span> <span class="str">"Not set"</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Radio - Fourth CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt; Selected Subject is %s&lt;/h2&gt;"</span> <span class="pun">%</span><span class="pln"> subject
</span><span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/html&gt;"</span>

Passing Text Area Data to CGI Program

TEXTAREA element is used when multiline text has to be passed to the CGI Program.

Here is example HTML code for a form with a TEXTAREA box −

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/textarea.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"post"</span> <span class="atn">target</span><span class="pun">=</span><span class="atv">"_blank"</span><span class="tag">&gt;</span>
<span class="tag">&lt;textarea</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"textcontent"</span> <span class="atn">cols</span><span class="pun">=</span><span class="atv">"40"</span> <span class="atn">rows</span><span class="pun">=</span><span class="atv">"4"</span><span class="tag">&gt;</span><span class="pln">
Type your text here...
</span><span class="tag">&lt;/textarea&gt;</span>
<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Submit"</span> <span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

The result of this code is the following form −

Below is textarea.cgi script to handle input given by web browser −

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span>
<span class="kwd">if</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'textcontent'</span><span class="pun">):</span><span class="pln">
   text_content </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'textcontent'</span><span class="pun">)</span>
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   text_content </span><span class="pun">=</span> <span class="str">"Not entered"</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span><span class="pun">;</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Text Area - Fifth CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt; Entered Text Content is %s&lt;/h2&gt;"</span> <span class="pun">%</span><span class="pln"> text_content
</span><span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>

Passing Drop Down Box Data to CGI Program

Drop Down Box is used when we have many options available but only one or two will be selected.

Here is example HTML code for a form with one drop down box −

<span class="tag">&lt;form</span> <span class="atn">action</span><span class="pun">=</span><span class="atv">"/cgi-bin/dropdown.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"post"</span> <span class="atn">target</span><span class="pun">=</span><span class="atv">"_blank"</span><span class="tag">&gt;</span>
<span class="tag">&lt;select</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"dropdown"</span><span class="tag">&gt;</span>
<span class="tag">&lt;option</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Maths"</span> <span class="atn">selected</span><span class="tag">&gt;</span><span class="pln">Maths</span><span class="tag">&lt;/option&gt;</span>
<span class="tag">&lt;option</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Physics"</span><span class="tag">&gt;</span><span class="pln">Physics</span><span class="tag">&lt;/option&gt;</span>
<span class="tag">&lt;/select&gt;</span>
<span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Submit"</span><span class="tag">/&gt;</span>
<span class="tag">&lt;/form&gt;</span>

The result of this code is the following form −

Maths
Physics

Below is dropdown.py script to handle input given by web browser.

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb 

</span><span class="com"># Create instance of FieldStorage </span><span class="pln">
form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span> 

<span class="com"># Get data from fields</span>
<span class="kwd">if</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'dropdown'</span><span class="pun">):</span><span class="pln">
   subject </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">.</span><span class="pln">getvalue</span><span class="pun">(</span><span class="str">'dropdown'</span><span class="pun">)</span>
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   subject </span><span class="pun">=</span> <span class="str">"Not entered"</span>

<span class="kwd">print</span> <span class="str">"Content-type:text/html\r\n\r\n"</span>
<span class="kwd">print</span> <span class="str">"&lt;html&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;title&gt;Dropdown Box - Sixth CGI Program&lt;/title&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/head&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;h2&gt; Selected Subject is %s&lt;/h2&gt;"</span> <span class="pun">%</span><span class="pln"> subject
</span><span class="kwd">print</span> <span class="str">"&lt;/body&gt;"</span>
<span class="kwd">print</span> <span class="str">"&lt;/html&gt;"</span>

Using Cookies in CGI

HTTP protocol is a stateless protocol. For a commercial website, it is required to maintain session information among different pages. For example, one user registration ends after completing many pages. How to maintain user’s session information across all the web pages?

In many situations, using cookies is the most efficient method of remembering and tracking preferences, purchases, commissions, and other information required for better visitor experience or site statistics.

How It Works?

Your server sends some data to the visitor’s browser in the form of a cookie. The browser may accept the cookie. If it does, it is stored as a plain text record on the visitor’s hard drive. Now, when the visitor arrives at another page on your site, the cookie is available for retrieval. Once retrieved, your server knows/remembers what was stored.

Cookies are a plain text data record of 5 variable-length fields:

  • Expires: The date the cookie will expire. If this is blank, the cookie will expire when the visitor quits the browser.
  • Domain: The domain name of your site.
  • Path: The path to the directory or web page that sets the cookie. This may be blank if you want to retrieve the cookie from any directory or page.
  • Secure: If this field contains the word “secure”, then the cookie may only be retrieved with a secure server. If this field is blank, no such restriction exists.
  • Name=Value: Cookies are set and retrieved in the form of key and value pairs.

Setting up Cookies

It is very easy to send cookies to browser. These cookies are sent along with HTTP Header before to Content-type field. Assuming you want to set UserID and Password as cookies. Setting the cookies is done as follows −

<span class="com">#!/usr/bin/python</span>

<span class="kwd">print</span> <span class="str">"Set-Cookie:UserID=XYZ;\r\n"</span>
<span class="kwd">print</span> <span class="str">"Set-Cookie:Password=XYZ123;\r\n"</span>
<span class="kwd">print</span> <span class="str">"Set-Cookie:Expires=Tuesday, 31-Dec-2007 23:12:40 GMT"</span><span class="pun">;</span><span class="pln">\r\n</span><span class="str">"
print "</span><span class="typ">Set</span><span class="pun">-</span><span class="typ">Cookie</span><span class="pun">:</span><span class="typ">Domain</span><span class="pun">=</span><span class="pln">www</span><span class="pun">.</span><span class="pln">tutorialspoint</span><span class="pun">.</span><span class="pln">com</span><span class="pun">;</span><span class="pln">\r\n</span><span class="str">"
print "</span><span class="typ">Set</span><span class="pun">-</span><span class="typ">Cookie</span><span class="pun">:</span><span class="typ">Path</span><span class="pun">=/</span><span class="pln">perl</span><span class="pun">;</span><span class="pln">\n</span><span class="str">"
print "</span><span class="typ">Content</span><span class="pun">-</span><span class="pln">type</span><span class="pun">:</span><span class="pln">text</span><span class="pun">/</span><span class="pln">html\r\n\r\n</span><span class="str">"
...........Rest of the HTML Content....</span>

From this example, you must have understood how to set cookies. We use Set-Cookie HTTP header to set cookies.

It is optional to set cookies attributes like Expires, Domain, and Path. It is notable that cookies are set before sending magic line “Content-type:text/html\r\n\r\n.

Retrieving Cookies

It is very easy to retrieve all the set cookies. Cookies are stored in CGI environment variable HTTP_COOKIE and they will have following form −

<span class="pln">key1</span><span class="pun">=</span><span class="pln">value1</span><span class="pun">;</span><span class="pln">key2</span><span class="pun">=</span><span class="pln">value2</span><span class="pun">;</span><span class="pln">key3</span><span class="pun">=</span><span class="pln">value3</span><span class="pun">....</span>

Here is an example of how to retrieve cookies.

<span class="com">#!/usr/bin/python</span>

<span class="com"># Import modules for CGI handling </span>
<span class="kwd">from</span><span class="pln"> os </span><span class="kwd">import</span><span class="pln"> environ
</span><span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> cgitb

</span><span class="kwd">if</span><span class="pln"> environ</span><span class="pun">.</span><span class="pln">has_key</span><span class="pun">(</span><span class="str">'HTTP_COOKIE'</span><span class="pun">):</span>
   <span class="kwd">for</span><span class="pln"> cookie </span><span class="kwd">in</span><span class="pln"> map</span><span class="pun">(</span><span class="pln">strip</span><span class="pun">,</span><span class="pln"> split</span><span class="pun">(</span><span class="pln">environ</span><span class="pun">[</span><span class="str">'HTTP_COOKIE'</span><span class="pun">],</span> <span class="str">';'</span><span class="pun">)):</span>
      <span class="pun">(</span><span class="pln">key</span><span class="pun">,</span><span class="pln"> value </span><span class="pun">)</span> <span class="pun">=</span><span class="pln"> split</span><span class="pun">(</span><span class="pln">cookie</span><span class="pun">,</span> <span class="str">'='</span><span class="pun">);</span>
      <span class="kwd">if</span><span class="pln"> key </span><span class="pun">==</span> <span class="str">"UserID"</span><span class="pun">:</span><span class="pln">
         user_id </span><span class="pun">=</span><span class="pln"> value

      </span><span class="kwd">if</span><span class="pln"> key </span><span class="pun">==</span> <span class="str">"Password"</span><span class="pun">:</span><span class="pln">
         password </span><span class="pun">=</span><span class="pln"> value

</span><span class="kwd">print</span> <span class="str">"User ID  = %s"</span> <span class="pun">%</span><span class="pln"> user_id
</span><span class="kwd">print</span> <span class="str">"Password = %s"</span> <span class="pun">%</span><span class="pln"> password</span>

This produces the following result for the cookies set by above script −

<span class="typ">User</span><span class="pln"> ID </span><span class="pun">=</span><span class="pln"> XYZ
</span><span class="typ">Password</span> <span class="pun">=</span><span class="pln"> XYZ123</span>

File Upload Example

To upload a file, the HTML form must have the enctype attribute set tomultipart/form-data. The input tag with the file type creates a “Browse” button.

<span class="tag">&lt;html&gt;</span>
<span class="tag">&lt;body&gt;</span>
   <span class="tag">&lt;form</span> <span class="atn">enctype</span><span class="pun">=</span><span class="atv">"multipart/form-data"</span> 
                     <span class="atn">action</span><span class="pun">=</span><span class="atv">"save_file.py"</span> <span class="atn">method</span><span class="pun">=</span><span class="atv">"post"</span><span class="tag">&gt;</span>
   <span class="tag">&lt;p&gt;</span><span class="pln">File: </span><span class="tag">&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"file"</span> <span class="atn">name</span><span class="pun">=</span><span class="atv">"filename"</span> <span class="tag">/&gt;&lt;/p&gt;</span>
   <span class="tag">&lt;p&gt;&lt;input</span> <span class="atn">type</span><span class="pun">=</span><span class="atv">"submit"</span> <span class="atn">value</span><span class="pun">=</span><span class="atv">"Upload"</span> <span class="tag">/&gt;&lt;/p&gt;</span>
   <span class="tag">&lt;/form&gt;</span>
<span class="tag">&lt;/body&gt;</span>
<span class="tag">&lt;/html&gt;</span>

The result of this code is the following form −

File:

Above example has been disabled intentionally to save people uploading file on our server, but you can try above code with your server.

Here is the script save_file.py to handle file upload −

<span class="com">#!/usr/bin/python</span>

<span class="kwd">import</span><span class="pln"> cgi</span><span class="pun">,</span><span class="pln"> os
</span><span class="kwd">import</span><span class="pln"> cgitb</span><span class="pun">;</span><span class="pln"> cgitb</span><span class="pun">.</span><span class="pln">enable</span><span class="pun">()</span><span class="pln">

form </span><span class="pun">=</span><span class="pln"> cgi</span><span class="pun">.</span><span class="typ">FieldStorage</span><span class="pun">()</span>

<span class="com"># Get filename here.</span><span class="pln">
fileitem </span><span class="pun">=</span><span class="pln"> form</span><span class="pun">[</span><span class="str">'filename'</span><span class="pun">]</span>

<span class="com"># Test if the file was uploaded</span>
<span class="kwd">if</span><span class="pln"> fileitem</span><span class="pun">.</span><span class="pln">filename</span><span class="pun">:</span>
   <span class="com"># strip leading path from file name to avoid </span>
   <span class="com"># directory traversal attacks</span><span class="pln">
   fn </span><span class="pun">=</span><span class="pln"> os</span><span class="pun">.</span><span class="pln">path</span><span class="pun">.</span><span class="pln">basename</span><span class="pun">(</span><span class="pln">fileitem</span><span class="pun">.</span><span class="pln">filename</span><span class="pun">)</span><span class="pln">
   open</span><span class="pun">(</span><span class="str">'/tmp/'</span> <span class="pun">+</span><span class="pln"> fn</span><span class="pun">,</span> <span class="str">'wb'</span><span class="pun">).</span><span class="pln">write</span><span class="pun">(</span><span class="pln">fileitem</span><span class="pun">.</span><span class="pln">file</span><span class="pun">.</span><span class="pln">read</span><span class="pun">())</span><span class="pln">

   message </span><span class="pun">=</span> <span class="str">'The file "'</span> <span class="pun">+</span><span class="pln"> fn </span><span class="pun">+</span> <span class="str">'" was uploaded successfully'</span>
   
<span class="kwd">else</span><span class="pun">:</span><span class="pln">
   message </span><span class="pun">=</span> <span class="str">'No file was uploaded'</span>
   
<span class="kwd">print</span> <span class="str">"""\
Content-Type: text/html\n
&lt;html&gt;
&lt;body&gt;
   &lt;p&gt;%s&lt;/p&gt;
&lt;/body&gt;
&lt;/html&gt;
"""</span> <span class="pun">%</span> <span class="pun">(</span><span class="pln">message</span><span class="pun">,)</span>

If you run the above script on Unix/Linux, then you need to take care of replacing file separator as follows, otherwise on your windows machine above open() statement should work fine.

<span class="pln">fn </span><span class="pun">=</span><span class="pln"> os</span><span class="pun">.</span><span class="pln">path</span><span class="pun">.</span><span class="pln">basename</span><span class="pun">(</span><span class="pln">fileitem</span><span class="pun">.</span><span class="pln">filename</span><span class="pun">.</span><span class="pln">replace</span><span class="pun">(</span><span class="str">"\\"</span><span class="pun">,</span> <span class="str">"/"</span> <span class="pun">))</span>

How To Raise a “File Download” Dialog Box ?

Sometimes, it is desired that you want to give option where a user can click a link and it will pop up a “File Download” dialogue box to the user instead of displaying actual content. This is very easy and can be achieved through HTTP header. This HTTP header is be different from the header mentioned in previous section.

For example, if you want make a FileName file downloadable from a given link, then its syntax is as follows −

<span class="com">#!/usr/bin/python</span>

<span class="com"># HTTP Header</span>
<span class="kwd">print</span> <span class="str">"</span><b><span class="str">Content-Type:</span></b><span class="str">application/octet-stream; name=\"FileName\"\r\n"</span><span class="pun">;</span>
<span class="kwd">print</span> <span class="str">"</span><b><span class="str">Content-Disposition:</span></b><span class="str"> attachment; filename=\"FileName\"\r\n\n"</span><span class="pun">;</span>

<span class="com"># Actual File Content will go here.</span><span class="pln">
fo </span><span class="pun">=</span><span class="pln"> open</span><span class="pun">(</span><span class="str">"foo.txt"</span><span class="pun">,</span> <span class="str">"rb"</span><span class="pun">)</span><span class="pln">

str </span><span class="pun">=</span><span class="pln"> fo</span><span class="pun">.</span><span class="pln">read</span><span class="pun">();</span>
<span class="kwd">print</span><span class="pln"> str

</span><span class="com"># Close opend file</span><span class="pln">
fo</span><span class="pun">.</span><span class="pln">close</span><span class="pun">()</span>

Take your time to comment on this article.

Follow by Email
Facebook0
Facebook
Google+
https://codingsec.net/2016/05/program-cgi-python/

Like the article? please consider sharing it. Thank you

Advertisment ad adsense adlogger