HTTP (HyperText Transfer Protocol) is the protocol that Web browsers use to talk to Web servers. The official specification for the HTTP standard is available on the W3 Consortium web server at:
http://www.w3.org/pub/WWW/Protocols/
Some more readable introductions can be found on the Yahoo HTTP page at:
http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/HTTP/
CGI (Common Gateway Interface) is a protocol used by Web servers to
run server programs. Scripts that support the CGI protocol are
sometimes called "CGI scripts"; this leads to the unfortunate
misperception that CGI is a language of its own.
The classic information on CGI is available on the NCSA server at:
http://hoohoo.ncsa.uiuc.edu/cgi/
If you haven't read this, read it now. If it doesn't click for you, you
can check the Yahoo CGI page at:
http://www.yahoo.com/Computers_and_Internet/Internet/World_Wide_Web/
(All one URL, leave out the line feed).
Try also the following URL for CGI programming in Perl:
http://www.perl.com/perl/faq/perl-cgi-faq.html
If you still don't get it, try one of the
"get-rich-quick-by-writing-CGI-scripts" books at your local bookstores.
One of the big differences between UNIX and Win32 platforms is that
on Win32 there's a difference between text or ASCII files and binary
file. To return a graphics file, you need to specify that the file is
a binary file, and that the standard output stream should accept
binary data. Try something like this:
PerlIS scripts need to add some extra header information, as noted
below.
Scripts running under PerlIS are a lot like "nph" scripts, as defined
in the CGI/1.1 specification (see question 7.2). You have to specify
the HTTP response status line as well as all headers for the response.
Here's a sample that works under PerlIS:
If you don't add the HTTP status line, as above, the browser will
assume that it is talking to an HTTP/0.9 server (the HTTP spec says that
the difference between a 1.0 and an 0.9 server is the presence of the
status line, and that good browsers should accept 0.9 responses). It
will then try and treat your response headers as part of the HTML you
are returning, so your headers will show up in the browser window,
which you probably don't want.
There's a misperception that if you don't add the HTTP status line,
PerlIS will add one for you, plus a Content-Type header. This is
false, and can be checked with a little sockets coding.
You should probably review the HTTP spec (see question 7.1) if you're
going to do any complicated PerlIS programming.
Philip Nelson has written a good exposition on the differences between
PerlIS and CGI (http://www.dct.com/~nelsonp/IISHeader.html).
[Any other suggestions?]
PerlIS sets an environment variable, PERLXS, for scripts that are
executed under PerlIS. The following script will run as a perl.exe
CGI script or as a PerlIS script. It checks the environment
variable to see if it needs to print out a status line.
The CGI.pm module works with Perl for Win32. It's available at
http://www-genome.wi.mit.edu/ftp/pub/software/WWW/cgi_docs.html
Note that you need to change the $OS variable in CGI.pm before
it will work correctly with Windows NT or Windows 95.
[Any other CGI modules work with Perl for Win32? -ESP]
You can use redirection to point the client browser to another file
or script, usually in a way that's invisible to the user. It requires
using the Location header as well as a special HTTP code, if
you're using PerlIS. The following code redirects the browser to a
simple text file.
Note that, if CGI (perl.exe) is used, the _server_ will retrieve the
location and send it to the browser, so the browser thinks that the
content is from the URL of your script. If PerlIS is used, the _browser_
has to retrieve the content itself, and the URL of the resource you
redirected to will be displayed to the user.
If you're using PerlIS, you should check out HTTP status codes 301 (Moved
Permanently), 302 (Moved Temporarily), and 303 (See Other) to see which
is most appropriate to your application. See question 7.1.
Cookies are packets of data that a server can give to a client to
identify the client in future interactions. They were first defined by
NetScape, and the definition of cookies can be found at:
http://home.netscape.com/newsref/std/cookie_spec.html
You can set the cookie as one of the CGI (for PerlIS, HTTP response)
headers in your file. You can get the cookie, if one is passed, throught
the HTTP_COOKIE environment variable. Here's a simple script that counts
how many times a user has accessed a page:
To set persistent cookies, define domains, specify expiration dates,
etc., refer to the specification above.
It's not, in general, possible to get the e-mail address of a user
without asking them for it. If you need an e-mail address, provide
the user with a form to fill in an address.
The HTTP specification (see question 6.2) defines an HTTP request
header , "From", that can contain the e-mail address of the user
making the connection. Your script can retrieve it using the
environment variable HTTP_FROM. However, it's rarely provided
and can't really be counted on.
There are all kinds of sneaky ways to determine where requests
come from -- like checking the IP address that was used to
connect -- but you can't figure out the e-mail address of the
user this way.
Generally, it's considered a violation of the user's privacy to
get their e-mail address without their knowledge. Perhaps that's
why it's so difficult.
There are several CGI script archives on the Web. You may not
be able to find exactly the script you want, but you will probably
find something that can be adapted to your needs.
Two of the most famous script pages are:
[Others? -ESP]
Note that most script archives have UNIX-targeted scripts, and you
may have to make some adaptations to them to make them run
(see question 5.7).
This is one of the most common questions on the Perl-Win32-Users list.
Occasionally it's phrased more like "I have a program to write.
Here are the specs. Please e-mail it to me by Friday." Hopefully
the reader can understand why these messages are usually answered
with flames or ignored.
The hard way to test your CGI programs from the command line is to
set up environment variables and a standard input stream just like
a Web server would (see the CGI 1.1 specification for more details
on this -- question 7.2).
The easy way is to use CGI.pm, the Perl module for CGI programming.
It provides an easy mechanism to run CGI programs, with arguments,
from the command line.
You are using PerlIS as your Perl interpreter on an IIS Web server
(this is set up by default by the install.bat program), but you're
not outputting an HTTP status line. See question 7.4 for details
on how to fix your problem.
Your Web server has been misconfigured. It doesn't know that it
should execute your Perl program, so it's just returning it to the
browser. See section 6 of this document for details on how to
configure your particular Web server to know that Perl scripts
should be executed.
7.2. What is CGI, and how do I get more information on it?
CGI___Common_Gateway_Interface/
7.3. How do I return a graphics file from a CGI script?
$MY_FILE_NAME = 'Penelope.jpg';
$CHUNK_SIZE = 4096;
open( MY_FILE, "<$MY_FILE_NAME" )
or die( "Can't open $MY_FILE_NAME: $!\n" );
print "Content-type: image/jpeg\r\n";
print "\r\n";
binmode( MY_FILE ); # These are crucial!
binmode( STDOUT );
while ( $cb = read( MY_FILE, $data, $CHUNK_SIZE ) )
{
print $data;
}
close( MY_FILE );
7.4. My CGI scripts don't seem to run right under PerlIS. What's wrong?
print <<"END";
HTTP/1.0 200 OK
Content-Type: text/html
<HTML>
<HEAD>
<TITLE>PerlIS Response</TITLE>
</HEAD>
<BODY>
This is a PerlIS response.
</BODY>
</HTML>
END
7.5. How does my script know if it's running under Perl for Win32 or PerlIS?
print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";
print <<"END";
Content-Type: text/html
<HTML>
<HEAD>
<TITLE>Both</TITLE>
</HEAD>
<BODY>
This script will work with perl.exe and PerlIS.
</BODY>
</HTML>
END
7.6. What CGI modules run with Perl for Win32?
7.7. How do I use redirection in my script?
print "HTTP/1.0 303 See Other\r\n" if $ENV{PERLXS} eq "PerlIS";
print <<"END";
Content-Type: text/plain
Location: /text/mytextfile.txt
END
7.8. What are cookies and how do I use them?
$cookie = $ENV{HTTP_COOKIE};
$count = ( $cookie ) ? (split( "=", $cookie ))[1] : 0;
$count++; # counting this visit.
if ( $count > 1 )
{
$welcome = "Welcome back for visit #$count to this page!";
}
else
{
$welcome = "Welcome to my page for the first time!";
}
$cookie = "COUNT=$count";
print "HTTP/1.0 200 OK\r\n" if $ENV{PERLXS} eq "PerlIS";
print <<"END";
Content-Type: text/html
Set-Cookie: $cookie
<HTML>
<HEAD>
<TITLE>Cookie Sample</TITLE>
</HEAD>
<BODY>
$welcome
</BODY>
</HTML>
END
7.9. How do I get the e-mail address of the user?
7.10. I need a CGI script to do X. Has anyone done it before?
7.11. How do I test my CGI programs that take arguments without running them through the Web server?
7.12. The "Content-Type" header I output from my CGI script shows up in the Web browser. What gives?
7.13. When I try to run a CGI script from my browser, it tries to download a file of type "application/x-perl" instead. What gives?