📄 ch19.htm
字号:
</PRE></BLOCKQUOTE><P>The output might look like this:<BLOCKQUOTE><PRE>Redirecting STDERR to STDOUTSetting Limits (CPU)Environment Variables: QUERY_STRING: '' PATH_INFO: '/~dbewley/cookie-test.pl' REMOTE_HOST: 'x2s5p10.dialin.iupui.edu' REMOTE_ADDR: '134.68.249.69' SCRIPT_NAME: '/cgi-bin/cgiwrapd'Trying to extract user/script from PATH_INFOExtracted Data: User: 'dbewley' Script: 'cookie-test.pl'Stripping user and script data from PATH_INFO env. var.Adding user and script to SCRIPT_NAME env. var.Modified Environment Variables: PATH_INFO: '' SCRIPT_NAME: '/cgi-bin/cgiwrapd/dbewley/cookie-test.pl'Sanitize user name: 'dbewley'-'dbewley'Sanitize script name: 'cookie-test.pl'-'cookie-test.pl'Log Request Opening log file. Writing log entry. Closing log file. Done logging request.User Data Retrieved: UserName: 'dbewley' UID: '8670' GID: '200' Directory: '/home/stu/d/dbewley'UIDs/GIDs Changed To: RUID: '8670' EUID: '8670' RGID: '200' EGID: '200'Current Directory: '/sparcus/users/dbewley/www/cgi-bin'Results of stat: File Owner: '8670' File Group: '200' Exec String: './cookie-test.pl'Output of script follows:=====================================================Set-Cookie: user=dbewley; expires=Wednesday, 09-Nov-99 00:00:00 GMT;path=/cgi-bin/; domain=.engr.iupui.edu; Set-Cookie: flag=black; expires=Wednesday, 09-Nov-99 00:00:00 GMT; path=/cgi-bin/; domain=.iupui.edu; Set-Cookie: car=honda:accord:88:LXI:green; expires=Wednesday, 09-Nov-9900:00:00 GMT; path=/cgi-bin/; domain=.engr.iupui.edu; Content-type: text/htmlCookies:<BR>flag = black<br>car = honda:accord:88:LXI:green<br>user = dbewley<br></PRE></BLOCKQUOTE><P>This output can be invaluable if your script is dying becauseof a syntax error before it can print an HTTP header to the browser.<BR><p><CENTER><TABLE BORDERCOLOR=#000000 BORDER=1 WIDTH=80%><TR><TD><B>Note</B></TD></TR><TR><TD><BLOCKQUOTE>If you'd like a more in-depth description of CGI Security, visit these Web sites:</BLOCKQUOTE></TD></TR></TABLE></CENTER><P><BLOCKQUOTE><PRE>http://www.csclub.uwaterloo.ca/u/mlvanbie/cgisec/# CGI Security Tutorialhttp://www.umr.edu/</FONT><FONT SIZE=1 FACE="Courier">~</FONT><FONT SIZE=2 FACE="Courier">cgiwrap/ # CGIwrap Home Page</PRE></BLOCKQUOTE><H2><A NAME="Cookies"><FONT SIZE=5 COLOR=#FF0000>Cookies</FONT></A></H2><P>Most Webmasters want to track the progress of a user from pageto page as they click about the site. Unfortunately, HTTP is a<I>stateless</I> protocol. Stateless protocols have no memory;they only understand the current command. This makes trackinga visitor through a site difficult at best. A user could visita site, leave, and come back a day or a minute later, possiblyfrom a different IP address. The site maintainer has no way ofknowing if this is the same browser or not.<P>One answer to this dilemma is to use <I>cookies</I> in your CGIprograms. Cookies can provide a way to maintain information fromone HTTP request to the next-remember the coNCept of persistentinformation?<P>A cookie is a small chunk of data, stored on the visitor's localhard drive by the Web server. It can be used to track your paththrough a Web site and develop a visitor's profile for marketingor informational purposes. Cookies can also be used to hold informationlike account numbers and purchase decisions so that shopping applicationscan be created.<H3><A NAME="CookieSecurity">Cookie Security</A></H3><P>There has been some controversy about whether cookies are secure.Although the cookie mechanism provides a way for a Web serverto write data to your hard disk the limitations are very strict.A client may only hold a maximum of 300 cookies at a time anda single server may only give 20 cookies to it. Cookies can onlybe 4 kilobytes each, iNCluding the name and data, so, at most,a visitor's hard disk may have 1.2 megabytes of hard disk beingused to store cookies. In addition, cookie data may only be writtento one file, usually called <TT>cookies.txt</TT>.<P>During a browsing session, Netscape stores cookies in memory,but when the browser is exited, cookies are written into a filecalled <TT>cookies.txt</TT>. On theMacintosh, the cookie jar is in a file called <TT>MagicCookie</TT>in the prefereNCes folder. The cookie file contains plain textas shown in Listing 19.3.<H3><A NAME="HowAreCookiesCreatedandRead">How Are Cookies Created and Read?</A></H3><P>Cookies are set using a <TT>Set-cookie</TT>:HTTP header with five possible fields separated with a semicolonand a space. These fields are:<UL><LI><B>cookie-name=cookie-value;</B>-name of the cookie and itsvalue. The name and the value combined must be less than 4 kilobytesin length.<LI><B>expiration=expiration-date;</B>-the date the cookie willbe deleted from the cookie file. You can delete a previously setcookie ahead of schedule by creating a second cookie with thesame name, path, and domain, but with an expiration date in thepast.<LI><B>path=cookie-path;</B>-combines with the domain name todetermine when a browser should show a cookie to the server.<LI><B>domain=server-domain;</B>-used to determine when a browsershould show a cookie to the server. Usually, cookies are createdwith the Web server's name without the <TT>www</TT>.For example, <TT>.foo.net</TT> insteadof <TT>www.foo.net</TT>. Notice thatthe leading period is retained.<LI><B>secure</B>-ensures that the cookie will be sent back onlyto the server when a secure HTTP connection has been established.</UL><P>When all of these elements are put together, they look like this:<BLOCKQUOTE><PRE>Set-Cookie: user_addr=ppp1.dialin.iupui.edu;expires=Wednesday, 09-Nov-99 00:00:00 GMT; path=/cgi-bin/;domain=.engr.iupui.edu; secure</PRE></BLOCKQUOTE><P>Listing 19.4 contains a program that both sets and read cookies.First, it will create four cookies and then it will read thosecookies from the <TT>HTTP_COOKIE</TT>environment variable. Inside the <TT>HTTP_COOKIE</TT>environment variable, the cookies are delimited by a semicolonand a space. The cookie fields are separated by commas, and thename-value pairs are separated by equal signs. In order to usecookies, you need to parse the <TT>HTTP_COOKIE</TT>variable at three different levels.<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Turn on the warning option.<BR>Turn on the strict pragma.<BR>Declare a variable to hold the expiration date and time of thecookies.<BR>Declare a variable to hold the domain name.<BR>Declare a variable to hold the path name.<BR>Set four cookies with different values.<BR>Read those four cookies from the environment; place them into</I><TT><I>%cookies</I></TT><I>.<BR>Start the HTML Web page.<BR>Display a text heading on the Web page.<BR>Start an HTML table.<BR>Display each cookie in a table row.<BR>End the table.<BR>End the Web page.<BR>Define the </I><TT><I>setCookie()</I></TT><I>fuNCtion.<BR>Create local variables from the parameter array.<BR>Send the </I><TT><I>Set-Cookie:</I></TT><I>HTTP header to the Web browser.<BR>Send the secure option only if requested.<BR>End the header with a newline.<BR>Define the </I><TT><I>getCookies()</I></TT><I>fuNCtion.<BR>Create a local hash to hold the cookies.<BR>Iterate over an array created by splitting the </I><TT><I>HTTP_COOKIE</I></TT><I>environment<BR>variable based on the ";" character sequeNCe.<BR>Split off the name of the cookie.<BR>Create a hash entry with the cookie's name as the key and therest of the cookie as the entry's value.<BR>Return the hash.</I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 19.4 19LST04.PL-How to Set and RetrieveCookies<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>#!/usr/local/bin/perl -wuse strict;my($expDate) = "Wednesday, 09-Nov-99 00:00:00 GMT";my($theDomain) = ".engr.iupui.edu";my($path) = "/cgi-bin/";setCookie("user", "dbewley", $expDate, $path, $theDomain);setCookie("user_addr", $ENV{'REMOTE_HOST'}, $expDate, $path, $theDomain) if defined($ENV{'REMOTE_HOST'});setCookie("flag", "black", $expDate, $path, ".iupui.edu");setCookie("car", "honda:accord:88:LXI:green", $expDate, $path, $theDomain);my(%cookies) = getCookies();print("Content-type: text/html\n\n");print("<HTML>");print("<HEAD><TITLE>The Cookie Display</TITLE></HEAD>");print("<BODY>");print("<H1>Cookies</H1>");print("<TABLE BORDER=1 CELLPADDING=10>");foreach (sort(keys(%cookies))) { print("<TR><TD>$_</TD><TD>$cookies{$_}</TD></TR>");}print("</TABLE>");print("</BODY>");print("</HTML>");sub setCookie { my($name, $val, $exp, $path, $dom, $secure) = @_; print("Set-Cookie: "); print("$name=$val, expires=$exp, path=$path, domain=$dom"); print(", $secure") if defined($secure); print("\n");}sub getCookies { my(%cookies); foreach (split (/; /,$ENV{'HTTP_COOKIE'})){ my($key) = split(/=/, $_); $cookies{$key} = substr($_, index($_, "=")+1); } return(%cookies);}</PRE></BLOCKQUOTE><HR><P>This program shows that the Web server stores a copy of any cookiesthat you set into the <TT>HTTP_COOKIE</TT>environment variable. It only performs one level of parsing. Inorder to create a really useful <TT>getCookies()</TT>fuNCtion, you need to split the cookie on the comma characterand then again on the equals character.<H3><A NAME="CanaVisitorsBrowserSupportCookies">Can a Visitor's Browser Support Cookies?</A></H3><P>One difficulty that you may have in using cookies is that notevery browser can support them. If you are using cookies, youneed a user-friendly way of telling a visitor that the featurehe or she is trying to use is not available to him or her.<P>Listing 19.5 contains a script that shows you a nice way of automaticallydetermining if a visitor's Web browser supports cookies. The CGIprogram will set a cookie and then redirect the visitor's Webbrowser back to itself with some additional path information.When the script (during its second invocation) sees the extrapath information, it checks for the previously created cookie.If it exists, the visitor's browser has passed the test. Otherwise,the visitor's browser does not support cookies.<P><IMG SRC="pseudo.gif" BORDER=1 ALIGN=RIGHT><p><BLOCKQUOTE><I>Turn on the warning option.<BR><I>Turn on the strict pragma.<BR><I>If there is no query information, then set a cookie and reloadthe script.<BR><I>Otherwise, see if the cookie set before the reload exits.<BR><I>If the cookie exists, the browser supports cookies.<BR><I>If the cookie does not exist, the browser does not supportcookies.</I></I></I></I></I></I></BLOCKQUOTE><HR><BLOCKQUOTE><B>Listing 19.5 19LST05.PL-How to Tell Whether theVisitor's Browser Supports Cookies<BR></B></BLOCKQUOTE><BLOCKQUOTE><PRE>#!/usr/bin/perl -wuse strict;if ($ENV{'QUERY_STRING'} ne 'TESTING') { print "HTTP/1.0 302 Moved Temporarily\n"; print "Set-Cookie: Cookie=Test\n"; print "Location: $ENV{'SCRIPT_NAME'}?TESTING\n\n";}else { if ($ENV{'HTTP_COOKIE'} =~ /Cookie=Test/) { print("Content-type: text/html\n\n"); print("<HTML>"); print("<HEAD><TITLE>$ENV{'HTTP_USER_AGENT'} supports Cookies</TITLE></HEAD>"); print("<BODY>"); print("Your browser, $ENV{'HTTP_USER_AGENT'}, supports theNetscape HTTP "); print("Cookie Specification."); print("</BODY></HTML>"); } else {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -