dcsimg

The Code Page 5

By ServerWatch Staff (Send Email)
Posted Aug 7, 1999


Let’s look at our program after we have collected our variables:

The first thing I did was to make a call to the ParseForm subroutine and the GetDate subroutine. A subroutine is a block of code that has a specific purpose or does something specific within your program. By executing the code within a subroutine you can call it at any point during the program by executing a call like below:

&parse_form;
&GetDate;

This comes in very handy if there is code you will use repeatedly during the program. The next thing I did was to define the first subroutine in the program, the PrintHeader subroutine. It is necessary to send the appropriate HTTP header to the browser so that it will know how to translate the information it is being passed. This is the most straightforward part of the CGI protocol. All subroutines start with the word sub and then the name we wish to give it.

sub PrintHeader {
print "Content-type: text/html\n\n";
}

Whenever text or HTML is output to the browser, we want to define our HTTP header as text or html exactly as above. This subroutine will be used several times throughout the program.

This next section examines the query string to see what information we are passing it after the question mark (?). In other words, when you first called the program, you called it with the syntax "scipt.cgi?exec" with exec being the query string. The program evaluates query strings with a standard if statement in this format " if (this expression is true) { Do This! } "

if ($ENV{'QUERY_STRING'} =~ /exec/i) {

In the above line, I took it one step further by allowing the client or user to pass it any string which contains the word exec in a non-case sensitive format. This is a wonderful example of Perl’s powerful regular expression and pattern matching. A regular expression is a string or series of characters that can be used to define a search pattern, such as a keyword. "ExECdog" will evaluate as true and thus execute the code block because we are searching for the regular expression "exec." If we wanted to require the user to type in a specific query string we would change the statement to if($ENV{'QUERY_STRING'} eq "exec"). You will notice that we no longer have the "=~" which searches for an instance of a string or pattern, and we have omitted the /…/i which tells Perl to not worry about the case of the word, i.e. exec is the same as EXEC. When we use eq "string" we are searching for the literal equal of the string, and thus only "exec" will evaluate as true. Note that we do not need the semicolons to terminate the end of our if expressions.

And then, if the expression evaluates as true, we execute our code block.

&PrintHeader;
print "Hey man it worked!\n<br>";
print "I'm executed!\n<br>";
print "$date\n<br>";
}

After we make a call to the PrintHeader subroutine (which prints the appropriate HTTP header), the program executes several simple print statements. You will note that, at the end of each of these lines, I put a Perl new line character (\n). These are not necessary for the execution of the program, but they do make it simple for more complex programs that will print a lot of information to your screen. The new line character is the equivalent of hitting the return key in your text editor. You should also notice that on the final line we print a scalar variable $date. You can include variables within your print statements exactly as if they were their normal string or numerical counterparts. Then we terminate our If statement and finish executing our block of code with the closing curly bracket. You should be made aware that certain characters are reserved by Perl and cannot be placed within a print statement, such as quotation marks. In order to print a line such as "Hey Bob" we would need to place a \ before the quotation marks. The line would look like this:

Print " \"Hey Bob\" ";

Now, if you didn’t pass the program a query string-- if you just called it as script.cgi-- it will execute the main portion of the program. We accomplish this by using an else statement, which says: "If you don’t pass me any query strings, I am going to do this!" The format is very similar to the if statement, only it does not need an expression to evaluate as it always will appear after an if type of statement, and thus, will execute only if the earlier statement evaluated as false. Below, we tell the program to execute the LogMe subroutine, or to record the information about the user:

else { # beginning of else statement
&LogMe # Call the LogMe subroutine
} # terminate else statement

The LogMe subroutine is the part of our program that does most of the work. When the subroutine is invoked, it opens a text file (which we named in our variable) and appends a line of text to the bottom of it containing some environmental variables. Environmental variables are bits of information set by the server that your program can access. These variables can contain information about your server, your program, and, in this case, the visitor.

sub LogMe {

The first thing we do in the LogMe subroutine is to open our text file. Whenever we work with a file in Perl, we assign it what is called a file handle. This file handle can be anything. Below, for clarity’s sake, I used the name FILE—but I could have used any word for the name. The next thing I do is tell the program how to access the file. By using >>, I am telling the program to append to the end of the file. There are three main ways you can open and access a file.

You can specify nothing and open the file for reading only

open(FILE,"$ServerPath$FileName")

You can open the file for appending

open(FILE,">>$ServerPath$FileName")

You can open the file for writing, and erase any previous information

open(FILE,">$ServerPath$FileName").

The pipe operators (||) or the logical or statement tells the program if you can’t open the file then write an error to the access log.

open(FILE,">>$ServerPath$FileName") || die ("no luck with opening file $dir$file");

We then print all of our variables to the file, using our file handle to specify which file we are writing to. You will notice that we are writing a mix of variables, our delimiter(|), and the environmental variables, which are part of the special %ENV associative array (don’t worry about it for now).

# Print the Environmental variables about the user to the text file separated by a | character
print FILE "$shortdate|$time|$ENV{'HTTP_REFERER'}|$ENV{'REMOTE_ADDR'}| $ENV{HTTP_USER_AGENT}|$ENV{'DOCUMENT_NAME'}\n";

Then we have to make sure that we close our file handle.

close(FILE);

Just to be sure that it worked, we again call our PrintHeader subroutine and print a simple line letting us know that we have been logged.



Comment and Contribute

Your name/nickname

Your email

(Maximum characters: 1200). You have characters left.