MAN page from Old RedHat 5.X perl-5.004-4.i386.rpm
PERLFAQ9
Section: Perl Programmers Reference Guide (1)
Updated: perl 5.004, patch 04
Index NAME
perlfaq9 - Networking ($Revision: 1.17 $,
$Date: 1997/04/24 22:44:29 $)
DESCRIPTION
This section deals with questions related to networking, the internet,and a few on the web.
My CGI script runs from the command line but not the browser. Can you help me fix it?
Sure, but you probably can't afford our contracting rates :-)
Seriously, if you can demonstrate that you've read the following FAQsand that your problem isn't something simple that can be easilyanswered, you'll probably receive a courteous and useful reply to yourquestion if you post it on comp.infosystems.www.authoring.cgi (if it'ssomething to do with HTTP, HTML, or the CGI protocols). Questions thatappear to be Perl questions but are really CGI ones that are posted tocomp.lang.perl.misc may not be so well received.
The useful FAQs are:
http://www.perl.com/perl/faq/idiots-guide.html http://www3.pair.com/webthing/docs/cgi/faqs/cgifaq.shtml http://www.perl.com/perl/faq/perl-cgi-faq.html http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html http://www.boutell.com/faq/
How do I remove HTML from a string?
The most correct way (albeit not the fastest) is to use
HTML::Parsefrom
CPAN (part of the libwww-perl distribution, which is a must-havemodule for all web hackers).
Many folks attempt a simple-minded regular expression approach, likes/<.*?>//g, but that fails in many cases because the tagsmay continue over line breaks, they may contain quoted angle-brackets,or HTML comment may be present. Plus folks forget to convertentities, like < for example.
Here's one ``simple-minded'' approach, that works for most files:
#!/usr/bin/perl -p0777 s/<(?:[^>'"]*|(['"]).*?\1)*>//gs
If you want a more complete solution, see the 3-stage striphtmlprogram in
http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/striphtml.gz.
How do I extract URLs?
A quick but imperfect approach is
#!/usr/bin/perl -n00 # qxurl - tchristAATTperl.com print "$2\n" while m{ < \s* A \s+ HREF \s* = \s* (["']) (.*?) \1 \s* > }gsix;This version does not adjust relative URLs, understand alternatebases, deal with
HTML comments, deal with
HREF and
NAME attributes inthe same tag, or accept URLs themselves as arguments. It also runsabout 100x faster than a more ``complete'' solution using the
LWP suiteof modules, such as the
http://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/xurl.gzprogram.
How do I download a file from the user's machine? How do I open a file on another machine?
In the context of an
HTML form, you can use what's known as
multipart/form-data encoding. The
CGI.pm module (available from
CPAN) supports this in the
start_multipart_form() method, which isn'tthe same as the
startform() method.
How do I make a pop-up menu in HTML?
Use the
<SELECT> and
<OPTION> tags. The
CGI.pmmodule (available from
CPAN) supports this widget, as well as manyothers, including some that it cleverly synthesizes on its own.
How do I fetch an HTML file?
One approach, if you have the lynx text-based
HTML browser installedon your system, is this:
$html_code = `lynx -source $url`; $text_data = `lynx -dump $url`;
The libwww-perl (
LWP) modules from
CPAN provide a more powerful way todo this. They work through proxies, and don't require lynx:
# print HTML from a URL use LWP::Simple; getprint "http://www.sn.no/libwww-perl/";
# print ASCII from HTML from a URL use LWP::Simple; use HTML::Parse; use HTML::FormatText; my ($html, $ascii); $html = get("http://www.perl.com/"); defined $html or die "Can't fetch HTML from http://www.perl.com/"; $ascii = HTML::FormatText->new->format(parse_html($html)); print $ascii; how do I decode or create those %-encodings on the web?
Here's an example of decoding:
$string = "http://altavista.digital.com/cgi-bin/query?pg=q&what=news&fmt=.&q=%2Bcgi-bin+%2Bperl.exe"; $string =~ s/%([a-fA-F0-9]{2})/chr(hex($1))/ge;Encoding is a bit harder, because you can't just blindly changeall the non-alphanumunder character (
\W) into their hex escapes.It's important that characters with special meaning like
/ and
?not be translated. Probably the easiest way to get this right isto avoid reinventing the wheel and just use the
URI::Escape module,which is part of the libwww-perl package (
LWP) available from
CPAN.
How do I redirect to another page?
Instead of sending back a
Content-Type as the headers of yourreply, send back a
Location: header. Officially this should be a
URI: header, so the
CGI.pm module (available from
CPAN) sends backboth:
Location: http://www.domain.com/newpage URI: http://www.domain.com/newpage
Note that relative URLs in these headers can cause strange effectsbecause of ``optimizations'' that servers do.
How do I put a password on my web pages?
That depends. You'll need to read the documentation for your webserver, or perhaps check some of the other FAQs referenced above.
How do I edit my .htpasswd and .htgroup files with Perl?
The
HTTPD::UserAdmin and
HTTPD::GroupAdmin modules provide aconsistent
OO interface to these files, regardless of how they'restored. Databases may be text, dbm, Berkley
DB or any database with a
DBI compatible driver.
HTTPD::UserAdmin supports files used by the`Basic' and `Digest' authentication schemes. Here's an example:
use HTTPD::UserAdmin (); HTTPD::UserAdmin ->new(DB => "/foo/.htpasswd") ->add($username => $password);
How do I make sure users can't enter values into a form that cause my CGI script to do bad things?
Read the
CGI security
FAQ, at
http://www-genome.wi.mit.edu/WWW/faqs/www-security-faq.html, and thePerl/
CGI FAQ at
http://www.perl.com/CPAN/doc/FAQs/cgi/perl-cgi-faq.html.
In brief: use tainting (see the perlsec manpage), which makes sure that datafrom outside your script (eg, CGI parameters) are never used ineval or system calls. In addition to tainting, never use thesingle-argument form of system() or exec(). Instead, supply thecommand and arguments as a list, which prevents shell globbing.
How do I parse an email header?
For a quick-and-dirty solution, try this solution derivedfrom page 222 of the 2nd edition of ``Programming Perl":
$/ = ''; $header = <MSG>; $header =~ s/\n\s+/ /g; # merge continuation lines %head = ( UNIX_FROM_LINE, split /^([-\w]+):\s*/m, $header );
That solution doesn't do well if, for example, you're trying tomaintain all the Received lines. A more complete approach is to usethe Mail::Header module from
CPAN (part of the MailTools package).
How do I decode a CGI form?
A lot of people are tempted to code this up themselves, so you'veprobably all seen a lot of code involving
$ENV{CONTENT_LENGTH} and
$ENV{QUERY_STRING}. It's true that this can work, but there arealso a lot of versions of this floating around that are quite simplybroken!
Please do not be tempted to reinvent the wheel. Instead, use theCGI.pm or CGI_Lite.pm (available from CPAN), or if you're trapped inthe module-free land of perl1 .. perl4, you might look into cgi-lib.pl(available from http://www.bio.cam.ac.uk/web/form.html).
How do I check a valid email address?
You can't.
Without sending mail to the address and seeing whether it bounces (andeven then you face the halting problem), you cannot determine whetheran email address is valid. Even if you apply the email headerstandard, you can have problems, because there are deliverableaddresses that aren't RFC-822 (the mail header standard) compliant,and addresses that aren't deliverable which are compliant.
Many are tempted to try to eliminate many frequently-invalid emailaddresses with a simple regexp, such as/^[\w.-]+\@([\w.-]\.)+\w+$/. However, this also throws out manyvalid ones, and says nothing about potential deliverability, so is notsuggested. Instead, seehttp://www.perl.com/CPAN/authors/Tom_Christiansen/scripts/ckaddr.gz ,which actually checks against the full RFC spec (except for nestedcomments), looks for addresses you may not wish to accept email to(say, Bill Clinton or your postmaster), and then makes sure that thehostname given can be looked up in DNS. It's not fast, but it works.
Here's an alternative strategy used by many CGI script authors: Checkthe email address with a simple regexp (such as the one above). Ifthe regexp matched the address, accept the address. If the regexpdidn't match the address, request confirmation from the user that theemail address they entered was correct.
How do I decode a MIME/BASE64 string?
The
MIME-tools package (available from
CPAN) handles this and a lotmore. Decoding
BASE64 becomes as simple as:
use MIME::base64; $decoded = decode_base64($encoded);
A more direct approach is to use the
unpack() function's ``u''format after minor transliterations:
tr#A-Za-z0-9+/##cd; # remove non-base64 chars tr#A-Za-z0-9+/# -_#; # convert to uuencoded format $len = pack("c", 32 + 0.75*length); # compute length byte print unpack("u", $len . $_); # uudecode and print How do I return the user's email address?
On systems that support getpwuid, the $< variable and theSys::Hostname module (which is part of the standard perl distribution),you can probably try using something like this:
use Sys::Hostname; $address = sprintf('%s@%s', getpwuid($<), hostname);Company policies on email address can mean that this generates addressesthat the company's email system will not accept, so you should ask forusers' email addresses when this matters. Furthermore, not all systemson which Perl runs are so forthcoming with this information as is Unix.
The Mail::Util module from CPAN (part of the MailTools package) provides amailaddress() function that tries to guess the mail address of the user.It makes a more intelligent guess than the code above, using informationgiven when the module was installed, but it could still be incorrect.Again, the best way is often just to ask the user.
How do I send/read mail?
Sending mail: the Mail::Mailer module from
CPAN (part of the MailToolspackage) is
UNIX-centric, while Mail::Internet uses Net::
SMTP which isnot
UNIX-centric. Reading mail: use the Mail::Folder module from
CPAN(part of the MailFolder package) or the Mail::Internet module from
CPAN (also part of the MailTools package).
# sending mail use Mail::Internet; use Mail::Header; # say which mail host to use $ENV{SMTPHOSTS} = 'mail.frii.com'; # create headers $header = new Mail::Header; $header->add('From', 'gnatAATTfrii.com'); $header->add('Subject', 'Testing'); $header->add('To', 'gnatAATTfrii.com'); # create body $body = 'This is a test, ignore'; # create mail object $mail = new Mail::Internet(undef, Header => $header, Body => \[$body]); # send it $mail->smtpsend or die; How do I find out my hostname/domainname/IP address?
A lot of code has historically cavalierly called the
`hostname`program. While sometimes expedient, this isn't very portable. It'sone of those tradeoffs of convenience versus portability.
The Sys::Hostname module (part of the standard perl distribution) willgive you the hostname after which you can find out the IP address(assuming you have working DNS) with a gethostbyname() call.
use Socket; use Sys::Hostname; my $host = hostname(); my $addr = inet_ntoa(scalar(gethostbyname($name)) || 'localhost');
Probably the simplest way to learn your
DNS domain name is to grokit out of /etc/resolv.conf, at least under Unix. Of course, thisassumes several things about your resolv.conf configuration, includingthat it exists.
(We still need a good DNS domain name-learning method for non-Unixsystems.)
How do I fetch a news article or the active newsgroups?
Use the Net::
NNTP or News::NNTPClient modules, both available from
CPAN.This can make tasks like fetching the newsgroup list as simple as:
perl -MNews::NNTPClient -e 'print News::NNTPClient->new->list("newsgroups")' How do I fetch/put an FTP file?
LWP::Simple (available from
CPAN) can fetch but not put. Net::
FTP (alsoavailable from
CPAN) is more complex but can put as well as fetch.
How can I do RPC in Perl?
A
DCE::RPC module is being developed (but is not yet available), andwill be released as part of the
DCE-Perl package (available from
CPAN). No
ONC::RPC module is known.
AUTHOR AND COPYRIGHT
Copyright (c) 1997 Tom Christiansen and Nathan Torkington.All rights reserved. See the
perlfaq manpage for distribution information.
Index
- NAME
- DESCRIPTION
- My CGI script runs from the command line but not the browser. Can you help me fix it?
- How do I remove HTML from a string?
- How do I extract URLs?
- How do I download a file from the user's machine? How do I open a file on another machine?
- How do I make a pop-up menu in HTML?
- How do I fetch an HTML file?
- how do I decode or create those %-encodings on the web?
- How do I redirect to another page?
- How do I put a password on my web pages?
- How do I edit my .htpasswd and .htgroup files with Perl?
- How do I make sure users can't enter values into a form that cause my CGI script to do bad things?
- How do I parse an email header?
- How do I decode a CGI form?
- How do I check a valid email address?
- How do I decode a MIME/BASE64 string?
- How do I return the user's email address?
- How do I send/read mail?
- How do I find out my hostname/domainname/IP address?
- How do I fetch a news article or the active newsgroups?
- How do I fetch/put an FTP file?
- How can I do RPC in Perl?
- AUTHOR AND COPYRIGHT
This document was created byman2html,using the manual pages.