Textbook, Chapter 9
Writing Server ScriptsRequirements for a server script:
Content-type: text/html
Location: http://www.cc.columbia.edu
We have chosen to use Perl.
Stages in the life of a server script:
It has all the strengths and weaknesses of a real document
It can't interact directly with the user in the way a normal program could (unless browser-side programming techniques are used (e.g., Java or JavaScript))
There is no easy way for your script to wait around for the user to respond
HTTP is a stateless protocol and your script is run from scratch every time the user requests its URL and stays running just long enough to produce a document
Your script can't easily tell whether the user is requesting its URL for the 50th or the 100th time (but ways around this exist)
Like any web document, the virtual document produced by your script must have a MIME type associated with it.
Technically the CGI protocol calls for you to end your header lines with a CR/LF sequence ("\r\n"
in Perl) but single newline characters work in practice just as well.(Note: if you're using CGI.pm you do not need to worry about this and many other things).
Perl Notes
Perl tutorial in lecture 3
Additional Perl notes in lab 4
Syntax is similar to C and various shell scripting languages
Has only three basic data structures:
$variable
)
@variable
)
Note: @variable
means the entire array.
%variable
)
Note: %variable
means the entire associative
array.
Associative arrays are also known as hashes.
Indexing:$result = "1" + 2 + 3; # $result is now 6 $result = "unbelievable"; # $result is now a string
$foo[0]
The first element of @foo
.
Indexing in an array is 0-based.
$foo[1]
The second element of @foo
.
$foo{'fred'}
The value of %foo
at index 'fred'
.
@a = ('tuna', 'cod', 'mackerel', 'herring'); %a = ( 'tuna' => '9.45/lb', 'cod', => '3.00/lb', 'mackerel', => '8.40/lb', 'herring => '2.30/lb' ); # note: this is a Perl5 shortcut # @a and %a are from different namespaces # same thing for a sclar variable called $a foreach $a (@a) { print $a, " --> ", $a{$a}, "\n"; }
<>
is used to retrieve a line of input from
the standard input (into $_
, magic variable).
Perl has lots of other magic variables, @_
,
$$
etc.
The statement
is a pattern matching operation.$foo =~ /pattern_to_match/
The prefix &
is used to invoke subroutines, as in
A definition of a subroutine can occur anywhere in the file but it's better to group any such definitions at the end or the beginning of the file.&process_query
A call to system
invokes a subshell and executes
the specified command.
A call to eval
evaluates the argument as a Perl
expression and returns the result.
Perl variables placed inside double-quoted strings interpolate, single-quoted strings don't. Example:
Backticks ($a = 'fred'; $b = "My name is $a"; $c = 'My Name is $a';
`
) as opposed to single quotes ('
)
cause the indicated program to be run, and the output of the program, if
any, is returned. The syntax
specifies a here-document. Text is as in a double-quoted string. Same can be achieved with:print <<EOF; Some text EOF
Perl5 introduces references. Examples:print qq{ Some text };
Perl5 has object-oriented syntax in which subroutine calls that are attached to variables become "methods". Here's an example in which we create a@a = ('a', 'b', 'c'); $ref = \@a; print $ref->[1]; # prints b ($a[1]) %a = ('a', 1, 'b', 2, 'c', 3); $ref = \%a; print $ref->{'a'}; # prints 1 $aux = \@a; print $ref->{$aux->[0]}; # prints 1
Dog
object, then call some of its methods.
Type$pet = new Dog('beagle'); $pet->play_pet_trick; $pet->eat('tuna');
man perltoot
for CGI.pm is object-oriented. We only make use of it.tucotuco.cs.indiana.edu% man perltoot Reformatting page. Wait... done Perl Programmers Reference Guide PERLTOOT(1) NAME perltoot - Tom's object-oriented tutorial for perl DESCRIPTION Object-oriented programming is a big seller these days. Some managers would rather have objects than sliced bread. Why is that? What's so special about an object? Just what is an object anyway? An object is nothing but a way of tucking away complex behaviours into a neat little easy-to-use bundle. (This is what professors call abstraction.) Smart people who have nothing to do but sit around for weeks on end figuring out really hard problems make these nifty objects that even regular people can use. (This is what professors call software reuse.) Users (well, programmers) can play with this little bundle all they want, but they aren't to open it up and mess with the insides. Just like an expensive piece of hardware, the contract says that you void the warranty if --More--(1%)
Reference: type man perlfunc
for:
Basic Scriptstucotuco.cs.indiana.edu% man perlfunc Reformatting page. Wait... done Perl Programmers Reference Guide PERLFUNC(1) NAME perlfunc - Perl builtin functions DESCRIPTION The functions in this section can serve as terms in an expression. They fall into two major categories: list operators and named unary operators. These differ in their precedence relationship with a following comma. (See the precedence table in the perlop manpage.) List operators take more than one argument, while unary operators can never take more than one argument. Thus, a comma terminates the argument of a unary operator, but merely separates the arguments of a list operator. A unary operator generally provides a scalar context to its argument, while a list operator may provide either scalar and list contexts for its arguments. If it does both, the scalar arguments will be first, and the list argument will follow. (Note that there can ever be only one list argument.) For instance, splice() has three scalar arguments followed by a list.
Hello, World! from a file.
A CGI calendar. Date, time, random quotations.#!/usr/bin/perl open (AB, "/u/dgerman/httpd/htdocs/index.html"); @file = <AB>; close(AB); $file = join('', @file); print "Content-type: text/html\n\n$file";
A redirection script.$CAL = '/usr/bin/cal'; $DATE = '/usr/bin/date'; $year = `$DATE +%Y`; $cal_txt = `$CAL $year`; ... print "<pre>$cal_txt</pre>";
All it needs to print is one line:Retrieving server and browser information from within scripts.Note: the URL could be relative.Location: http://www.cs.indiana.eduThe example in your book randomly picks a file. Other response header fields can be used too:
Content-length
Last-modified
Expires
Pragma
Creating and processing fill-out forms.Server software and communication protocols SERVER_SOFTWARE name and version number GATEWAY_INTERFACE CGI version number SERVER_PROTOCOL HTTP version number Server configuration SERVER_NAME tucotuco.cs.indiana.edu SERVER_PORT 19800 Information about user authentication AUTH_TYPE e.g., Basic Authentication REMOTE_USER username that goes with that Information about the remote host REMOTE_HOST DNS name of remote host REMOTE_ADDR IP address of remote host REMOTE_IDENT name of remote user when using identd auth Information about the current reques REQUEST_METHOD GET, HEAD, or POST SCRIPT_NAME virtual path to the script (URL) PATH_INFO extra URL path info after script name if any PATH_TRANSLATED extra path info converted in physical path QUERY_STRING the part that follows ? if present CONTENT_TYPE for POST requests only MIME type of the attached info CONTENT_LENGTH for POST only the length of the attached information Information generated by the browser HTTP_ACCEPT list of MIME types that browser accepts HTTP_USER_AGENT name and version number of browser HTTP_REFERER page user was viewing before HTTP_COOKIE magic cookie: string that can identify a browser session HTTP_XXXXXXX other headers browser decides to sendPrinting the environment variables:The <ISINDEX> tag#!/usr/bin/perl print "Content-type: text/plain\n\n"; foreach $var (keys %ENV) { print "$var --> $ENV{$var} \n"; }
You need to get at the query string.A user-adjustable calendar.Not to be confused with
QUERY_STRING
in%ENV
.Query string included in the URL (GET)
Query string generated by an <ISINDEX> tag$query = $ENV{'QUERY_STRING'}Query string generated by a fill-out form (with POST)@ARGVread(STDIN, $buffer, $ENV{'CONTENT_LENGTH'});
Allow the user to specify the year(s).CGI.pm: a perl library for writing CGI.Use all three methods.
InstallationOther query processing librariesYou don't need to do this on burrow but useful to know.
Usage
Retrieving and setting script parameters.
Calling CGI.pm methods with named arguments.use CGI; $query = new CGI; foreach $name ($query->param) { $value = $query->param($name); print "$name => $value\n"; }Creating the HTTP header.@veggies = $query->param('vegetables'); @veggies = $query->param(-name=>'vegetables');Creating HTML forms.print $query->header; # returns Content-type: text/html\n\n (default) # print $query->header(-type=>'image/gif');Same thing with one print statement:print $query->start_html; print $query->start_form(-action=>'/cgi-bin/printenv', -method=>'POST'); print $query->textfield (-name=>'username', -size=> 12, -value=> 'Fill this in!', -override=>1); # sticky CGI.pm print $query->submit(-label=>'Push me!'); print $query->end_form;Access to environment variables.print $query->start_html, # <--- notice the comma $query->start_form(-action=>'/cgi-bin/printenv', -method=>'POST'), # <--- notice the comma $query->textfield (-name=>'username', -size=> 12, -value=> 'Fill this in!', -override=>1), # <--- notice the comma $query->submit(-label=>'Push me!'), # <--- notice the comma $query->end_form; # <--- semicolon, end of listDebugging scripts with CGI.pm library.if ($query->request_method eq 'GET') { ... } else { ... }Documentation and examples.At least you get an idea if they compile. You can also specify keywords lists or parameter lists from the prompt.tucotuco.cs.indiana.edu% ./formelms (offline mode: enter name=value pairs on standard input) a=b ^D
- CGI Docs (Stein)
- Form Elements (Lecture 7)
- State Machines (Lecture 7)
- Feedback Form (Lecture 7)
- Clickable Images (Lecture 7)
- File Upload (Lecture 7)
cgi-lib.pl
(Perl 4)
CGI::
(Perl 5)
cgic
The most common kind of CGI scriptWriting safe scriptsThe template for this is:
- accepts input from the user
- does some work
- produces an HTML document showing the results
- if the user provides no input it generates and returns an input document
- print the header
- print the start of the HTML document
- attempt to fetch the query string
if there is no query stringthis is the user's first access to this page so generate and return input document (form or isindex tag)else (there's a query string)do the work and synthesize a document giving the result of the request (or an acknowledgement that the request was processed)- print the end of the HTML document, including a signature
Pictures are indexed by keywords.Preserving state information between invocations of a scriptSearch looks at keywords and then produces a document that has links to the images found.
Percentage of keywords found are also reported with the links.
Maintaining state with the URLReturning nontext documents from scriptsWe've done this in the menu program (lecture 4).Maintaining state with hidden fieldsThe simple calculator (lecture 4).Saving information with a session IDThe state machines (lecture 7).
Using basic authentication
Cookies (yours or Netscape's)
Making thumbnails imagesAdvanced techniquesImages from scratch (using GD.pm)
Covered in lecture 10 thoroughly.
Background jobsThe script forks a process.The tricky part is to return the result to the user.
Use e-mail for message with notification or results (collect the address first) or provide an interface for the user to check if the results have become available.
Content negotiationProtect the user from confusion.Check what her/his browser accepts.
File uploadsNetscape extension first.Format.
CGI.pm makes it easy (lecture 7).
So does Steve Brenner's
cgi-lib.pl
(Perl 4).
FramesScripts can directly specify which frame to load their output into by including ain the HTTP header.Window-target:
Server Push/Client PullUpdating the page upon server/client request.Neat feature before Java.
FastCGIExtensions to the standard to make the connection more permanent.