7.7 Information Received by the CGI Program


ACGI program receives three types of information from the server:

  • Client request information

  • Path information

  • Posted data

We look at each of these in turn .

7.7.1 Request Information

The webserver makes available to the CGI script information about the current request called session information . This information can be retrieved with several provided methods .

Client information consists of the following:

  • remote_host() ” the name of the client machine

  • user_name() ” the name of the user if authenticated

  • user_agent() ” the browser that the user is surfing with

  • referer() ” the referer (remember, this is misspelled )

  • path_info() ” the path information

  • query_string() ” the query string

The first four items are straightforward. The two functions path_info() and query_string() are a bit more involved, and they are discussed in detail in Sections 7.7.2 and 7.7.3. Server information consists of:

  • server_name() ” the hostname of the webserver

  • server_software() ” the name of the webserver software

  • virtual_host() ” the name of the virtual host

  • server_port() ” the port that the server is using (usually 80)

  • script_name() ” the name of the script

Most of this client/server information is available in the CGI programs through the environment inherited by the script and stored in %ENV . For instance, if we want the query string, we can look in $ENV{QUERY_STRING} . If we want the server name, we can look at $ENV{SERVER_NAME} . Most programmers prefer the CGI.pm functions listed earlier, but TMTOWTDI.

We can show the use of many of these methods in a single example:

 #! /usr/bin/perl  # info4.cgi  use CGI :standard;  print      header(),      start_html(More System Information),      h1(Client Information),      Here is some information about the client:,      ul(li(The remote host: , remote_host()),         li(The user agent: , user_agent()),         li(The referer: , referer())),  h1(Server Information),  Here is some information about the server:,  ul(li(The server name: , server_name()),     li(The server software: , server_software()),     li(The server port: , server_port()),     li(The script name: , script_name())),  end_html(); 

The result of this program can be seen in Figure 7.8.

Figure 7.8. More CGI information

graphics/07fig08.jpg

The example uses two methods to generate HTML lists, ul() and li() . The ul() method generates <UL> ... </UL> and the li() method generates <LI> ... </LI> . The methods nest, so the result of the CGI.pm method is the same as:

 <UL><LI>The remote host: www.opensourcewebbook.com</LI>      <LI>The user...</LI></UL> 

7.7.2 Path Information

The path information is text that is passed into the CGI program if it exists in the URL after the CGI program name and before the question mark (we talk about the question mark next , when we discuss processing posted form data). This data can be used for a variety of reasons: as information about a path, data that causes the CGI program to perform in a specific manner, or just about anything that you need.

For instance, let's say we are writing a messaging system allowing the user to post to and read from message boards. There are a number of boards and in each board a number of messages. We could pass the board that the user is browsing and the message they are reading in through the path information, as in this URL:

 http://www.example.com/cgi-bin/messageboard/webprogramming/19312 

In this example, the name of the program is messageboard (yes, it could be named messageboard.cgi , but this is a matter of preference), the board the user is browsing is webprogramming , and the message is number 19312 (perhaps a message about this book?).

So the path information can be just about any information that you choose to pass in to the CGI program. The path information can be obtained either from %ENV , the hash that contains the CGI program's environment:

 $env_path = $ENV{PATH_INFO}  ; 

or by using the CGI method path_info() :

 $method_path = path_info()  ; 

Here's an example of a CGI program that displays the path information using both %ENV and path_info() . Place this code in the file /var/www/cgi-bin/path_info.cgi :

 #! /usr/bin/perl  # path_info.cgi  use strict;  use CGI :standard;  #get the path from %ENV, then from the  # CGI method path_info()  my $env_path    = $ENV{PATH_INFO}  ;  my $method_path = path_info()      ;  print      header,      start_html(-title => Path Information,                 -bgcolor => #ffffff),      From %ENV: ,      b($env_path),      br(),      From path_info(): ,      b($method_path),      end_html(); 

As an example, load one of these URLs in your browser: http://localhost/cgi-bin/path_info.cgi/foo/bar or www.opensourcewebbook.com/cgi-bin/path_info.cgi/foo/bar. Notice that the text " /foo/bar " that follows the CGI program name is the path information. Proof of this can be seen in Figure 7.9.

Figure 7.9. CGI path information

graphics/07fig09.gif

7.7.3 Processing Posted Form Data

Were you wondering when we were going to talk about the mysterious query string? That time has come.

The third class of information that the CGI script receives is posted form data (if any). An example is data that comes from an HTML form that has as its action the CGI program in question. Here is a form example stored in /var/www/html/cgi/nameage.html :

 <html>  <head>  <title>Enter Your Name and Age</title>  </head>  <body bgcolor="#ffffff">  <form action="/cgi-bin/nameage.cgi" method="get">  Name: <input type="text" name="yourname">  <br>  Age: <input type="text" name="age">  <br>  <input type="submit" value="Click to Submit">  </form>  </body>  </html> 

This program results in a web page like that shown in Figure 7.10.

Figure 7.10. Enter name and age

graphics/07fig10.gif

When the user clicks the Click to Submit button, the program given as the action ”in this case /cgi-bin/nameage.cgi , which corresponds to the executable program /var/www/cgi-bin/nameage.cgi ”is executed. Posted data is sent to the program ”here the posted data is the name of the fields ( yourname and age ) and the values entered into those fields.

Notice that when the data is sent to the program, the URL resembles this:

 http://localhost/cgi-bin/nameage.cgi?yourname=J.+Random+Luser&age=55 

The program's name is followed by a question mark ( ? ). The question mark is then followed by this funny looking text:

 yourname=J.+Random+Luser&age=55 

This data is called URL encoded data and is passed into the CGI program through the query string . It is the data from the form that is encoded into a format that can be sent to the webserver through the URL.

If we wanted to look at this data in the program, we could get the query string information by executing query_string() . But usually we don't grab the data directly. Instead, we let CGI.pm take care of things for us.

The query string format is a collection of form widget name/value pairs separated by the equal sign ( = ), each pair separated from the next by an ampersand ( & ). So in the example, there are two name/value pairs:

 yourname=J.+Random+Luser  age=55 

The text that is posted may contain text that is not legal in a URL (such as a space). This text is encoded before being sent to the server. Spaces are replaced with the plus sign ( + ), as shown in the example, and other disallowed characters are replaced with a percent character followed by the hexadecimal representation of that character's ASCII value. For instance, the exclamation point character ( ! ) is replaced with %21 .

The URL contains the posted data following the " ? " because the form was created with method="GET" . The GET method passes the data through the URL in the query string. The alternative is to use method="POST" . This method passes the data to the CGI program through its standard input instead of through the URL. Either way, CGI.pm handles the data passed in. These are the contents of nameage.cgi :

 #!/usr/bin/perl  # nameage.cgi  use strict;  use CGI :standard;  my $name   = param(yourname)  John Doe;  my $age    = param(age)       0;  my @params = param();  print      header(),      start_html(Your Name and Age),      "Hello $name, you are $age years old.",      hr(),      The parameters entered are: ,      b("@params"),      end_html(); 

The most important method shown in this example is the param() method. This method works either with or without an argument. If param() is called with an argument:

 $name = param(yourname)  John Doe; 

it returns the value posted for that form widget. Note that the name of the form text widget for the name is " yourname ". Passed with that name is the value that the user enters. Executing param( yourname ) returns the value entered by the user into the form, or the empty string if the user does not enter any text into that widget. Recall from Chapter 4 that the " logical or " operator used in this statement, , is really shorthand for this logic:

 if (param(yourname)ne) {      $name = param(yourname);  } else {      $name = John Doe;  } 

This makes sure that $name is valid no matter what the user enters, defaulting to " John Doe " if the user doesn't enter a value.

If param() is called with no arguments:

 @params = param(); 

it returns a list of all the widget names in the form ” yourname , age . If the user entered the name J. Random Luser and the age 55 into the form, the result of nameage.cgi would look like Figure 7.11.

Figure 7.11. Name and age results

graphics/07fig11.gif

Let's examine a more complicated example showing many more form widgets. The example in /var/www/html/cgi/widgets.html can be found online at http://localhost/cgi/widgets.html.txt or www.opensourcewebbook.com/cgi/widgets.html.txt. It creates the form shown in Figure 7.12.

Figure 7.12. Widget examples

graphics/07fig12.gif

After the beginning HTML, we see the creation of the form:

 <form action="/cgi-bin/widgets.cgi" method="post"> 

This means that when this form is submitted, all the data in the form are sent to the program widgets.cgi . Then a bunch of widgets are created.

A text widget, or a one-line box in which the user can enter text:

 Programming language: <input type="text" name="language" value="Perl"> 

A text widget, or a multiline area in which the user can enter lines of text:

 Comments:  <br>  <textarea name="comments" cols="20" rows="5"></textarea> 

A radio button group allowing the user to select one-of-many choices:

 Rate the coolness:  <input type="radio" name="coolness" value="cool"> cool  <input type="radio" name="coolness" value="very cool"> very cool  <input type="radio" name="coolness" value="ice cold" checked> ice cold 

A check box, or an on-or-off selection:

 I will learn more about Perl and CGI:  <input type="checkbox" name="learnmore" value="yes" checked> Yes 

Two menus are defined with the <select> tag.

 I will use this operating system:  <select name="operating_system" size="1">      <option>Linux</option>      <option>Solaris</option>      <option>HPUX</option>  </select>  <br>  My favorite animal(s):  <select name="animal" size="3" multiple>      <option>Penguin</option>      <option>Camel</option>      <option>Llama</option>      <option>Panther</option>  </select> 

The first is a menu button that is clicked, and then the item desired is selected. This is a menu button because the size is set to 1, so only one item is shown in the GUI until the widget is clicked. The other <select> widget is a scrolling list box ”since the size is 3, three selections are shown in the box, and the others are viewable by scrolling (hmmm, scrolling list box...that's a good name for this widget). Note that the attribute multiple is indicated, which means the user can select more than one option by control-clicking the additional items. The fact that more than one item can be selected becomes important when the values selected are grabbed.

The submit and reset buttons are created:

 <input type="submit" value="Submit Form">  <input type="reset" value="Reset Form"> 

If the submit button is clicked, the data is sent to the program widgets.cgi . If the reset button is clicked, the form is reset to its original values.

The associated CGI script to process the posted data is in the file /var/www/cgi-bin/widgets.cgi . You can find this file at http://localhost/cgi/widgets.cgi or www.opensourcewebbook.com/cgi/widgets.cgi.

First we see something important:

 #! /usr/bin/perl  # widgets.cgi  use strict;  use CGI :standard; 

It is a Perl script. Yes! Also, we are using the CGI.pm module in the standard mode, as we have done before.

Then we see the code to grab the posted data:

 # get the posted form data  my $language         = param(language)         Perl;  my $comments         = param(comments)         ;  my $coolness         = param(coolness)         Ice Cold;  my $learnmore        = param(learnmore)        no;  my $operating_system = param(operating system) Linux;  # use an array here since we can choose more than one animal  my @animal           = param(animal); 

Note how each variable that is being assigned posted data has an appropriate default value. Also, because more than one animal can be selected (remember, the <select> widget had the multiple attribute set, so the user can select more than one animal), the param() function is assigned to an array ”CGI.pm returns all the items selected as a list, here assigned to @animal .

Then we see the code to print the content:

 print      header(),      start_html(-title   => Process Widgets,                 -bgcolor => #ffffff),      h1(Process widgets),      You entered the following information into the form:,      br(),      Language: ,      b($language),      br(),      Comments:,      br(),      b($comments),      br(),      Coolness level: ,      b($coolness),      br(),      You want to learn more about Perl and CGI: ,      b($learnmore),      br(),      Your operating system of choice is: ,      b($operating_system),      br(),      Your favorite animal(s) is/are: ,      b("@animal"),      end_html; 

This looks like the code we have seen before. A sample result is shown in Figure 7.13.

Figure 7.13. Widget example result

graphics/07fig13.gif

This works well enough, but there is a drawback. There are two files to maintain: widgets.html and widgets.cgi . Wouldn't it be nice to simply have one file that we need to maintain? This is possible if we write the CGI program more generally to have two distinct functions.

  • If no data is posted, build the form.

  • If data is posted, process the data.

This can be done by modifying widgets.cgi with an if statement, as shown in /var/www/cgi-bin/widgets2.cgi . You can view it in its entirety at http://localhost/cgi/widgets2.cgi or www.opensourcewebbook.com/cgi/widgets2.cgi. A quick look at the overall program shows that it is one big if ... else :

 if (param) {      # we have posted parameters, so process them  } else {      # no posted data, so build the form  } 

The if portion of widgets2.cgi resembles the previous example, widgets.cgi :

 if (param) {      # we are here if there was any data posted, so process it      # get the posted form data      my $language         = param(language)          Perl;      my $comments         = param(comments)          ;      my $coolness         = param(coolness)          Ice Cold;      my $learnmore        = param(learnmore)         no;      my $operating_system = param(operating system)  Linux;      # use an array here since we can choose more than one animal      my @animal           = param(animal);      print          header(),          start_html(-title   => Process Widgets,                     -bgcolor => #ffffff),          h1(Process widgets),          You entered the following information into the form:,          br(),          Language: ,          b($language),          br(),          Comments:,          br(),          b($comments),          br(),          Coolness level: ,          b($coolness),          br(),          You want to learn more about Perl and CGI: ,          b($learnmore),          br(),          Your operating system of choice is: ,          b($operating_system),          br(),          Your favorite animal(s) is/are: ,          b("@animal"),      end_html; 

The else part, executed if no parameters are posted, is one big here document (after the header() is printed). The nice thing about the here document is that the HTML printed is more or less exactly the same as we saw in widgets.html (we won't show all of it):

 }else{     # if we are here, then we need to build the form     # so print the header, then the html     print         header(),         <<EOHTML;  <html>  <head>  <title>An Example of Form Widgets</title>  </head>  <body bgcolor="#ffffff">  <h1>An Example of Form Widgets</h1>  <form action="/cgi-bin/widgets2.cgi" method="post">  Programming language: <input type="text" name="language" value="Perl">  <br>  .  .  .  </form>  </body>  </html>  EOHTML  } 

You can try it out at this book's web site or on your own server by going to http://localhost/cgi-bin/widgets2.cgi or www.opensourcewebbook.com/cgi-bin/widgets2.cgi.



Open Source Development with Lamp
Open Source Development with LAMP: Using Linux, Apache, MySQL, Perl, and PHP
ISBN: 020177061X
EAN: 2147483647
Year: 2002
Pages: 136

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net