200 likes | 321 Views
3.0.1.3.3 Introduction to CGI – Session 3. Introduction to CGI: Data persistence in CGI apps Keeping track on user Caching data Cookies: pieces of information stored on the user side ‘Live’ demo of a web application which uses it all. Introduction to the problem.
E N D
3.0.1.3.3 Introduction to CGI – Session 3 • Introduction to CGI: • Data persistence in CGI apps • Keeping track on user • Caching data • Cookies: pieces of information stored on the user side • ‘Live’ demo of a web application which uses it all 3.0.1.3.3 - Introduction to CGI
Introduction to the problem • HTML - stateless protocol, as it doesn’t have a direct methods for tracking individual users. Practicing indirect method for tracking individual users is called maintaining state. Cases, where we need maintaining state: • Shopping cart: Internet stores • Caching the results of computationally intense analysis • Tracking the ‘clicking through’ (pages of the site which user requests using site’s hyperlinks) • Automatic login • Tracking the date of the last visit 3.0.1.3.3 - Introduction to CGI
Possible solutions and tools • Hidden fields • <INPUT TYPE=“hidden” NAME=“Secret” VALUE=“foobar”> • Allow to pass variables between forms through multiple web pages, limited by • Temporary file names • Temporary file names and ids are necessary for unique identification of a user. • Special tools for data storage • Serialization tools like Storable help to record complex data structures effortlessly. • Client-side cookies • Although this technique has its own limitation – for example, users have to enable cookies in their browser – this method of identifying users on the web is very popular. 3.0.1.3.3 - Introduction to CGI
Using hidden fields Hidden fields may be used for passing information betweenpages, containing forms (essentially, between forms) and are not visible in a browser. However, hidden fields are visible when user view HTML source. And, of course, CGI-style: <FORM NAME=“MY_FORM” ACTION=“my_form.cgi” METHOD=“POST”> .. .. <INPUT TYPE = “hidden” NAME = “id” VALUE = “e08a5676b1289a1787900cd6787cab” </FORM> print $q->hidden(-name => “id”, -value => “e08a5676b1289a1787900cd6787cab” ); 3.0.1.3.3 - Introduction to CGI
Hidden fields example .. print header(-type=>"text/html");; print start_html(-title=>"Testing CGI"); my $name = param('Y_name'); my $age = param('Y_age'); if($name && $age){ print h2("Your name is $name and you are $age years old"), end_html; exit; }elsif($name){ print start_form(-action=>"hidden_test.cgi", -method=>"post"), "Enter Your Age:", textfield(-name =>"Y_age"), hidden(-name => "Y_name", -value=> $name), br; }else{ print start_form(-action=>"hidden_test.cgi", -method=>"post"), "Enter Your Name:", textfield(-name =>"Y_name"), br; } print submit(-name =>"Send_it", -value=>"Send"), end_form; print end_html; 3.0.1.3.3 - Introduction to CGI
Using Digest::MD5 module for generation of session ids Digest::MD5 module • This module gives user the access to MD5 Message Digest algorithm which can digest a string of arbitrary length into 128-bit “fingerprint” or message digest. • $md5->hexdigest • The length of the returned string will be 32 and it will only contain characters from this set: '0'..'9' and 'a'..'f'. • $md5->b64digest • The length of the returned string will be 22 and it will only contain characters from this set: 'A'..'Z', 'a'..'z', '0'..'9', '+' and '/'. use Digest::MD5; my $md5 = new Digest::MD5; $md5->add(“A”, ”B”, .. $Z); The things you might want to add to md5: time, $$, random number 3.0.1.3.3 - Introduction to CGI
An example of using Digest::MD5 In this example we concatenate all environment variables and digest these values into hexadecimal string #!/usr/local/bin/perl -w use strict; use CGI qw(:standard); use CGI::Carp qw(fatalsToBrowser); use Digest::MD5; my $md5 = new Digest::MD5; map{md5->add($_)} values %ENV; my $string = $md5->md5_hexdigest; print header(-type=>"text/html"), start_html(-title=>"MD5 test"), h2("Your session id is $string"), end_html; Your session id is 6df23dc03f9b54cc38a0fc1483df6e21 3.0.1.3.3 - Introduction to CGI
Temporary file name generation • use POSIX qw(tmpnam); .. use POSIX qw(tmpnam); use IO::File; my $tmpfilename; opendir(DIR,"./tmp") or die "couldn't read from dir"; my @entries = readdir DIR; close DIR; while(1){ $tmpfilename = tmpnam(); map{if("/tmp/".$_ eq $tmpfilename){next;}} @entries; last; } my $fh = new IO::File; my @data = ("horse","duck","camel"); $fh->open(">.$tmpfilename") or die "Couldn't write to [$tmpfilename]\n"; for(@data){ print $fh $_."\n"; } $fh->close; /tmp/fileAfg78C 3.0.1.3.3 - Introduction to CGI
Using temporary filename for storing data on a server • use IO::File • Provides a method for generating anonymous temporary filehandles • use Storable (store, retrieve); • Storable – module allowing serialization of data, i.e. recording and retrieving complex data structures as data stream (without parsing input or output) use IO::File; . . . my $tmp_fh = new_tmpfile IO::File; Temporary files get erased as soon as the script exits use Storable; store \%table, 'file'; $hashref = retrieve('file'); 3.0.1.3.3 - Introduction to CGI
Locking files • Web is a multi-user environment • There might be a situation when different user might try to access the same file (i.e. simultaneously read and write to a file) • Insecure approach: use CGI; .. my $email = param(“email”) || “Anonymous”; my $comment = param(“comment”) || “No comments”; open FILE, “>> /usr/local/apache/data/guestbook.txt” or &printError(“Can not add an entry to the guestbook!”); print FILE “From $email: $comment\n\n”; close FILE; .. File locking allows to limit the access to a file to one user at a time 3.0.1.3.3 - Introduction to CGI
Example of using flock() : simple .cgi counter use Fcntl qw(:flock); use CGI qw(:standard); my $file = 'counts.txt'; my $SEMAPHORE = $file.'.lck'; my $counts; open(S,">>$SEMAPHORE") or die "SEMAPHORE: $!"; flock(S,LOCK_EX) or die "flock() failed for $SEMAPHORE: $!"; if(open(FH,"$file")){ $counts = <FH>; close FH; } else{$counts = 0;} open(FH,">$file")or die "Can't open $file: $!"; print FH ++$counts; close FH; close S; print header, start_html('Counter Test'), h1("You are visitor $counts"), end_html; You are visitor 2002030 flock() does not protect files from writing, it works through giving a ‘notice’ to other processes which use flock() 3.0.1.3.3 - Introduction to CGI
Cookies • Cookies were originally developed by Netscape and are small pieces of information which can be user id, the date of last visit of a webpage, etc. 3.0.1.3.3 - Introduction to CGI
Syntax for setting a cookie • HTTP Cookie parameters: • Name -name The id for cookie • Value -value The value assigned for cookie • Domain -domain The browser will only return the cookie for URLs within this domain • Expires -expires This tells the browser when cookie expires • Path -path The browser will only return the cookie for URLs below this path • Secure -secure The browser will only return the cookie for secure URLs using https protocol my $cookie = $q->cookie(-name => “my_id”, -value => 12345, -domain => ”.bcgsc.ca”, -expires => “+1m”, -path => “/cgi”, -secure => 1 ); 3.0.1.3.3 - Introduction to CGI
Setting and reading cookies print “Set-Cookie: $cookie\n”; CGI-style: print $q->header( -type => “text/html”, -cookie => $cookie); To read the cookie script passes a name to CGI method cookie: Remember that having cookies with the same name will result in reading only one cookie my $cookie = $q->cookie( -name => “my_cookie”); 3.0.1.3.3 - Introduction to CGI
Example of using a cookie • .. • my $q = new CGI; • my $Page_Cookie; • my %Values = $q->cookie('page_values'); • my $name = $q->param('Name') || $Values{Name}; • my $title = $q->param('Title') || $Values{Title}; • my %Newvalues = (Name => $name || "", • Title => $title|| "“ • ); • unless(%Newvalues && $Newvalues{Name}){ • print $q->header(-type=>"text/html"), • $q->start_html(-title =>"Enter Name"), • $q->start_form(-name =>"Cookie_form", • -action=>"cookie.cgi", • -method=>"post"), • "Your Name", • $q->popup_menu(-name=>"Title", • $q->option(["Mr","Mrs","Ms","Dr"])), • $q->textfield(-name=>"Name"), • $q->br, • $q->submit(-name =>"Submit", • -value=>"send"), • $q->end_form, • $q->end_html; • exit; • } • .. 3.0.1.3.3 - Introduction to CGI
Cookies (continues) • .. • $Page_Cookie = $q->cookie(-name =>'page_values', • -expires=>'+1d', • -value =>\%Newvalues • ); • print $q->header(-type =>"text/html", • -cookie=>$Page_Cookie), • $q->start_html(-title=>"Cookie Test"), • $q->h2("Hello $title $name!"), • $q->end_html; 3.0.1.3.3 - Introduction to CGI
Summary on tools: • Generation of unique ids: • use Digest::MD5 • use POSIX qw(tmpnam) • use IO::File; • Caching data: • use Storable; • use Cache::Cache; • use DataDumper; • use Fcntl qw(flock); • Cookies: • $cookie = $q->cookie(-name=> “my_cookie”, -value=>$bar); • print $q->header(-type => “text/html”, -cookie=>$cookie); • $cookie = $q->cookie(‘my_cookie’); • .. • return $ENV{UNIQUE_ID} if exists $ENV{UNIQUE_ID}; 3.0.1.3.3 - Introduction to CGI
Debugging CGI scripts Running Scripts from Command Line Depending on the version of CGI.pm file parameters to a script may be passed in two different ways: 2.56 and earlier - prompts for pairs of name=value finish input with Crl+D (Crl+Z in Windows) 2.57 and later: pass the parameter as arguments to your script localhost> ./my_script.cgi (offline mode: enter name=value pairs on standard input) item=foo price=bar It is also possible to use ptkdb debugger which is written using Tk library for GUI localhost> ./my_script.cgi item=foo price=bar 3.0.1.3.3 - Introduction to CGI
Some good practices for coding CGI • Use strict Helps trap syntax abusage as using unquoted words in your statements, using symbolic links (they are evil, remember?) • Check the status of your system calls (open, eval, system) open (FILE, “/usr/local/apache/data/guestbook.txt”); • Trap die (use Carp module) use CGI::Carp(fatalsToBrowser) • Lock file (or use database connection) Avoid headaches by allowing user to access a file one by one • Set automatic flushing for buffer (especially when using system calls) $| = 1; 3.0.1.3.3 - Introduction to CGI
3.0.1.3.3 Introduction to CGI – Session 3 • Tools for maintaining state: • Hidden fields may be used to re-submit previously entered information • Temporary file names may be generated with POSIX • Cookies: use to save some user information on the client side 3.0.1.3.3 - Introduction to CGI