|
To access the contents, click the chapter and section titles.
HTML 4.0 Sourcebook
Lines 22 through 29 attempt to lock the file (flock($cntfile,2)). Locking the file means that the running perl program is the only program that can modify the file and ensures that two users cannot simultaneously attempt to change the file. The program tries four times to lock the file, waiting one second between attempts. If it fails, it sets a default value for the string containing the counter value ($cnt) and skips the part of the program that actually reads the count file. If it succeeds in locking the file, it proceeds to the next phase, beginning at line 30, where the count file is opened, the count is read and incremented by 1, and the count is rewritten to the file, overwriting the old value. The file is then closed and the lock is released (flock($cntfile, 8)), freeing it for use by other users. Line 39 begins the processing of the file returned to the client. The file is opened at line 40 and read in at line 42, into the array @array. When finished, the file is closed (line 43). Line 45 prints the required content-type header. Lines 46 through 48 print the data to standard output, replacing every occurrence of the string <!-- counter --> by the counter string (line 47)this is either the counter value from line 33 or the error string from line 25. And that is it. The count is inserted, the document is returned, and the counter has been incremented by 1. There are several limitations to this program. First, it is slow, since the program has to check every line for the string <-- counter -->. A second problem is associated with file permissions: The server that launches a gateway program usually runs with very limited ability to create and modify files in the directories on the server; thus this gateway program, when launched by the server, will probably not be able to create or modify the count file. If this is the case, the document author will have to create the count file by hand and change the Figure 11.6 Listing of the perl gateway program counter.pl, which inserts an access count into a designated HTML document. The path to the designated HTML document is passed as extra path information in the URL used to access this program. Line numbers, in italics, are added for reference purposes onlythey are not present in the original program. 1 #!/usr/local/bin/perl 2 if (defined($ENV{PATH_TRANSLATED}) ) { 3 $path = $ENV{PATH_TRANSLATED}# get file from extra path info 4 } 5 else { 6 &f_error(No file specified\n); 7 } 8 $file = $path; # Path to file to be processed 9 $cnt_file = $path; 10 $cnt_file =~ s/.*\///; # Extract substring for counter filename 11 $path =~ s/\/[\w-.;~]*$/\//;# get path to directory 12 13 $cnt_file = $path...$cnt_file;# counter filename = path/.filename 14 15 if( !(-e $cnt_file) ) { # If count file doesnt exist, create it 16 open(CNTFILE, > $cnt_file) || 17 &f_error(Unable to create count file\n); 18 print CNTFILE 0; 19 close(CNTFILE); 20 } 21 $loops = 0; # try 4 times to lock the count file 22 while ( flock($cnt_file,2) == -1 ) { 23 $loops++; 24 if( $loops > 4) { 25 $cnt = -1 (Unable to lock counter)\n; 26 goto PROCESS; # If unable to lock, skip it. 27 } 28 sleep 1; 29 } 30 open(CNTFILE, +< $cnt_file)# open the counter file 31 || &f_error(Unable to open counter file\n); 32 $cnt = <CNTFILE>; # get the current count 33 $cnt++; # increment count by one 34 seek(CNTFILE, 0, 0); # rewind to start of file 35 print CNTFILE $cnt; # write out new count 36 close(CNTFILE); # close the count file 37 flock($cntfile, 8); # Unlock the count file 38 39 PROCESS: 40 open(FILE, $file) # Open file to process 41 || &f_error(Unable to open file for processing\n); 42 @array= <FILE>; # Read in the file 43 close(FILE); 44 # Print out the document 45 print Content-type: text/html\n\n; 46 foreach (@array) { # scan for special string, and 47 s/<!-- counter -->/ $cnt /i;# replace it by the count 48 print $_; 49 } 50 # Error Handling Subroutine 51 sub f_error { 52 print Content-type text/plain\n\n; 53 print <HTML><HEAD>\n<TITLE>Error In Counter Script</TITLE>; 54 print \n</HEAD><BODY>\n<h2>Error</h2>\n<P>Error message: $_[0]; 55 print \n<P> Please report this problem to someone.; 56 print \n</BODY></HTML>; 57 die; 58 } file characteristics so that the gateway program can modify it. Finally, we note that this program only counts accesses that pass through the gateway program. If the document is accessed via the URL http://some.where.edu/path/file.html then the access is not counted. In this regard, it is far better to invoke a counter using a parsed HTML document and a server-side exec. There are several useful features you might want to add. For example, you might want to exclude your own machine or domain from the counting process, or you may prefer keeping all the count values in a single counter database file as opposed to having one file per document. These and other variations on page counters are available in a number of counter programs, many of which are far more sophisticated than this example. The latter part of this chapter lists sites where such resources can be found. Example 29: Inserting a Randomly Selected HTML FragmentOne useful parsed HTML trick is to use a gateway program to insert a randomly selected HTML text snippet into an HTML document. The perl program rot-new.pl is a simple implementation, which selects a file at random from a specified directory and inserts it inline within the parsed document. Assuming that the program is located in the servers cgi-bin/ directory, the relevant server-side include instruction is: <!--#exec cgi=/cgi-bin/rot-new.pl --> When the server parses this document, it replaces this string by the output of the program rot-new.pl. Figure 11.7 gives the listing for the program rot-new.pl. The ideas are very simple. At line 8, the program prints a text/html content-type headerrecall that this is required of CGI programs returning data to a parsed HTML document. The second block, at lines 12 to 14, retrieves a directory listing for the directory /svc/www/InsTestthis is the directory that contains the insertions. Lines 15 to 17 convert the filenames into absolute paths, excluding non-data files (i.e., directories), and store the list of files in the array @filenames. The subsequent if statement at line 22 checks to see if there are any files in this listthe program exits if there are none. The alternate block of the if , beginning at line 25, selects a filename at random (line 28), opens the file (line 29), reads in the file content and then closes the file (line 31), and prints the content to standard output (line 32). The output is the text included within the HTML document.
|
Products | Contact Us | About Us | Privacy | Ad Info | Home
Use of this site is subject to certain Terms & Conditions, Copyright © 1996-2000 EarthWeb Inc. All rights reserved. Reproduction whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Read EarthWeb's privacy statement. |