Transcript CGI

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 message body 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
• file sharing, etc.
– Many CGI scripts use slow interpreted languages
• Many use PERL
Web Server Architecture
Socket
Queue
Web Server
newSkt
connect
// Thread pseudo code
while(1)
{
newSkt = DeQ()
// Communicate
// using HTTP
}
Client
// Server pseudo code
// Create Socket Queue
// Create Thread pool
while(1)
{
newSkt = accept(…)
EnQ(newSkt)
}
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 in the message body
• via stdin - just read and parse appropriately
Launching CGI
void LaunchCGI
{
//create pipes
fork()
if (child)
{
//allocate and setup the environment variable array
//fill env array with HTTP headers
//format HEADER_NAME=header value
//use dup2 to duplicate the pipes onto stdin & stdout
exec
}
else
{
// Write the body of the HTTP message on the child’s stdin pipe
// Read the headers sent back on the child’s stdout pipe
// Parse out the Content-Length
// Send the appropriate response line
// Forward the headers on to the client on the socket
// Read Content-Length bytes from child’s stdout pipe
// Write Content-Length bytes to client on socket
// close the pipes
// wait on the child – waitpid
// close the socket
}
}
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
– "post" means they’re passed in the HTTP header and message
body (and therefore aren’t seen on the browser address bar).
– "get" means they’re passed through the query string of the URL
itself, and therefore seen in the address bar in the web browser
(given to CGI program 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 type attribute
•
•
•
•
•
•
•
•
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 questionnaire
– A search engine that remembers past searches
• Main techniques
–
–
–
–
Hidden fields
URL rewriting
Cookies
Session ID
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
Cookies
• A small piece of information stored on
the client machine and returned to the
server.
• Implemented using HTTP headers
– Cookie
– Set-Cookie
• 4 K bytes per cookie
• 20 cookies per server or domain at least
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.
Details
Browser
GET /index.html HTTP/1.1
Host: www.example.org
Server
HTTP/1.0 200 OK
Content-type: text/html
Set-Cookie: name=value
Set-Cookie: name2=value2; Expires=Wed, 09 Jun 2021 10:18:14
GMT
Browser
GET /spec.html HTTP/1.1
Host: www.example.org
Cookie: name=value; name2=value2
Accept: */*
Session ID
• Generate a session ID
– use as filename or DB key – store session info
– Large random number
– Time, PID, etc.
• Pass the session ID using url rewriting or
hidden fields or cookies
– 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)
Note: You can also use a database – We will cover this in the lab