Transcript CGI-1

CGI
CGI Programming
• What is "CGI"?
– Common Gateway Interface
• A means of running an executable program via
the Web.
• CGI is not a Perl-specific concept. Almost any
language can produce CGI programs - even
C++ (gasp!!)
• However, Perl does have a *very* nice interface
to creating CGI methods
Common Gateway Interface
• User selects page that will be provided by a CGI
application
• Server recognizes dynamic page
– By extension (usually .cgi)
– By location
• Server spawns the app
– Passes arguments via stdin
– HTTP header info available in environment variables
• App passes HTML page back to server via stdout
• Server sends page back to user
CGI
• Advantages
– Original approach (substantial installed base)
– Use any language compatible with or available on the server
– Many free CGI scripts (www.cgidir.com)
• Disadvantages
– Overhead of spawning/killing the app repeatedly
– Concurrent hits on page cause multiple parallel copies of the
app in memory
– Many CGI scripts use slow interpreted languages
• Many use PERL
Web Server Architecture
Client
Web
Server
stdin
stdout
CGI
program
GET vs. POST
GET /path/file.html?n=v HTTP/1.1
Host: www.host1.com:80
[blank line here]
POST /path/script.cgi HTTP/1.0
From: [email protected]
User-Agent: HTTPTool/1.0
Content-Type: application/x-www-form-urlencoded
Content-Length: 32
home=Cosby&favorite+flavor=flies
CGI & Parameters
• All input to a CGI program comes from:
– Environment
– stdin
HTTP headers
Message Body
• Get
– Query string - Everything after the ?
• Goes in environment variable QUERY_STRING
• POST
– All data comes the message body
• via stdin - just read and parse appropriately
PERL & CGI
• PERL is nice for CGI
• Steps
– Parse the environment
• REQUEST_METHOD = POST or GET
– If GET
• QUERY_STRING contains url encoded args
– If POST
• Body of message contains binary data
• Process body by reading stdin appropriately
– CGI program must know how to react to what is coming in
– Use mime type in CONTENT_TYPE
• Can be done manually - But why?
– Use cgi library
#!/usr/bin/perl
use CGI;
$cgi = new CGI;
if ($reqmeth eq "POST")
{
print "<h2>This is a POST</h2>\n";
print "The Query String is empty. The arguments come in the\n";
print "body of the HTTP request message. Here it is.\n";
}
elsif ($reqmeth eq "GET")
# Start the page by outputing the Content-type header
{
print $cgi->header;
print "<h2>This is a GET</h2>\n";
print $cgi->start_html("Using the CGI class");
print "The Query String is in the environment\n";
print "<h1>This is a list of the environment variables</h1>\n"; }
else
print $cgi->hr();
{
print "<h2>Unknown method</h2>\n";
print "<pre>\n";
}
foreach $var (sort(keys(%ENV))) {
$val = $ENV{$var};
$val =~ s|\n|\\n|g;
$val =~ s|"|\\"|g;
print "${var}=\"${val}\"\n";
}
print "</pre>\n";
print $cgi->hr();
$reqmeth = $cgi->request_method();
print "<pre>\n";
@names = $cgi->param;
$i = 0;
foreach $n (@names)
{
print "Arg $i name is: [$n]\n";
$value = $cgi->param($n);
print "Arg $i value is: [$value]\n";
$i++;
}
print "</pre>\n";
print "<h2>All done now... bye</h2>\n";
PERL cgi functions
•
•
•
•
•
•
•
•
•
•
start_html
h1
p
checkbox_group
popup_menu
start_form
end_form
param
header
Best help – http://search.cpan.org/src/LDS/CGI.pm-3.25/cgi_docs.html
PERL Here docs
• Multiple print statements are sometimes a
pain
print<<“EOF”;
This is a test
<h1>Hi</h1>
EOF
• Goes until it finds the marker
File Locking
•
•
•
•
•
$LOCK_SH = 1;
$LOCK_EX = 2;
$LOCK_NB = 4;
$LOCK_UN = 8;
open(LOCKFILE, ">>lockfile") or die "Unable
to open lockfile: $!\n";
• $err = flock LOCKFILE, $LOCK_EX;
• print LOCKFILE $ARGV[0], ",", time(), ".\n";
• flock LOCKFILE, $LOCK_UN;
Forms
– Most (not all) CGI scripts are contacted
through the use of HTML forms.
– A form is an area of a web page in which
the user can enter data, and have that
data submitted to another page.
– When user hits a submit button on the
form, the web browser contacts the script
specified in the form tag.
Creating a Form
• <form method="post" action="file.cgi"> ... <input
type="submit" value="Submit Form"> </form>
• Method attribute specifies how parameters are
passed to the CGI program.
– "post" means they’re passed in the HTTP header and
message body (and therefore aren’t seen anywhere).
– "get" means they’re passed through the query string of the
URL itself, and therefore seen in the address bar in the web
browser (seen in the QUERY_STRING header).
– Action attribute specifies which program you want the web
browser to contact.
– <input>is a tag used to accept User data.
– type="submit" specifies a Submit button. When user clicks
this button, browser contacts file specified in action attribute.
Form Input Types
– Many different ways of getting data from user. Most
specified by <input>tag, type specified by typeattribute
•
•
•
•
•
•
•
•
textfield a text box
checkbox a check box
radio a Radio button
password password field (text box, characters display as ******)
Hidden - hidden field (nothing displayed in browser)
Submit - Submit button. Submits the form
Reset - Reset button. Clears form of all data.
Button - A button the user can press (usually used w/
javaScript.
• File - field to upload a file
• Image - an image user can click to submit form
Preserving State in CGI
Preserving State
• HTTP is stateless, but we would like to save
and remember state
– Shopping cart
– Interactive or multipart questionaire
– A search engine that remembers past searches
• Main techniques
–
–
–
–
Hidden fields
URL rewriting
Session ID
Cookies
Hidden Fields
• Add hidden input fields to a form
– <input type = “hidden”….>
• Advantages
– Easy
• Disadvantages
– Data is continually sent back and forth
– Data is easily readable & changeable
– Only available if there is a form
URL Rewriting
• Create links dynamically
– Contain information in the url
– http://blah.com/page?state=a+b…
• Advantages
– Fairly simple also
• Disadvantages
– If state is complex, must encode
– User visible and modifiable
Session ID
• Generate a session ID - use as filename
– Large random number
– Time, PID, etc.
• Pass the session ID using url rewriting or
hidden fields
– More secure because user can only change the
session ID and most likely will be wrong
• Advantages
– Good when state is large, complex, or private
– Easy using CGI.pm
SessionID example
$query = new CGI;
…
open(FILE, “>$sessionID.sav”) || die “…”;
$query->save(FILE);
close(FILE)
$cgi = new CGI;
…
open(FILE, “$sessionID.sav”) || die “…”;
$oldquery = new CGI(FILE);
close(FILE)
Cookies
• A small piece of information stored on
the client machine and returned to the
server.
• http headers
– Cookie
– Set-Cookie
• 4 K bytes per cookie
• 20 cookies per server or domain
Set-Cookie (server side)
Set-Cookie: name=value
- URL encoded text
[;EXPIRES=dateValue]
- Wdy, DD-Mon-YY HH:MM:SS GMT
[;DOMAIN=domainName]
- valid domain name
[;PATH=pathName]
- path to send cookie
[;SECURE]
- transmitted only if communication is SSL
Cookie (client-side)
Cookie: name=value1; name=value2
All cookie name=value pairs that match
the current path are sent.
Cookie example
• Client requests document and receives
– Set-Cookie: cust=W_Coyote; path=/;
• Client stores cookie
• When client requests another URL below /,
client sends
– Cookie: cust=W_Coyote;
• Server may set multiple cookies with different
paths
• Client returns all matching cookies
Cookies
• CGI.pm has some nice functions for the
creation and use of cookies
$mycookie = $query->cookie(