今天想要做个PHP扩展插件来实现网页截图,这个我一年前就在想到现在才开始作,在网上找了很多资料,最后发现自己需要用CGI所以就开始配置自己的CGI
首先安装apache的时候就已经默认安装了CGI只需要少许的改动,就可以用了
AddHandler cgi-script .cgi去掉前面的#号该文件在httpd.conf或者是mime.conf这该文件
ScriptAliasScriptAlias指令使Apache允许执行一个特定目录中的CGI程序。当客户端请求此特定目录中的资源时,Apache假定其中所有的文件都是CGI程序并试图运行它。
ScriptAlias指令形如:
ScriptAlias /cgi-bin/ /usr/local/apache2/cgi-bin/
如果Apache被安装到默认位置,默认的配置文件httpd.conf中就会有上述配置。ScriptAlias与Alias指令非常相似,都是定义了映射到一个特定目录的URL前缀,两者一般都用于指定位于DocumentRoot以外的目录,其不同之处是ScriptAlias又多了一层含义,即URL前缀后面的任何文件都被视为CGI程序。所以,上述例子会指示Apache:任何以/cgi-bin/开头的资源都将映射到/usr/local/apache2/cgi-bin/目录中,且视之为CGI程序。
例如,如果有URL为http://www.example.com/cgi-bin/test.pl的请求,Apache会试图执行/usr/local/apache2/cgi-bin/test.pl文件并返回其输出。当然,这个文件必须存在而且可执行,并以特定的方法产生输出,否则Apache返回一个出错消息。
ScriptAlias目录以外的CGI由于安全原因,CGI程序通常被限制在ScriptAlias指定的目录中,这样,管理员就可以严格控制谁可以使用CGI程序。但是,如果采取了恰当的安全措施,则没有理由不允许其他目录中的CGI程序运行。比如,你可能希望用户在UserDir指定的宿主目录中存放页面,而他们有自己的CGI程序,但无权访问cgi-bin目录,这样,就产生了运行其他目录中CGI程序的需求。
允许CGI在任意目录执行需要两个步骤:第一步,必须用AddHandler或SetHandler指令激活cgi-script处理器。第二步,必须在Options指令中启用ExecCGI选项。
用Options显式地允许CGI的执行可以在主配置文件中,使用Options指令显式地允许特定目录中CGI的执行:
<Directory /usr/local/apache2/htdocs/somedir>
Options +ExecCGI
</Directory>
上述指令使Apache允许CGI文件的执行。另外,还必须告诉服务器哪些文件是CGI文件。下面的AddHandler指令告诉服务器所有带有cgi或pl后缀的文件是CGI程序:
AddHandler cgi-script .cgi .pl
.htaccess文件.htaccess指南示范了怎样在没有权限修改httpd.conf文件的情况下激活CGI程序。
用户目录为了允许用户目录中所有以”.cgi“结尾的文件作为CGI程序执行,你可以使用以下配置:
<Directory /home/*/public_html>
Options +ExecCGI
AddHandler cgi-script .cgi
</Directory>
如果你想在用户目录中指定一个cgi-bin子目录,其中所有的文件都被当作CGI程序,你可以这样配置:
<Directory /home/*/public_html/cgi-bin>
Options ExecCGI
SetHandler cgi-script
</Directory>
然后就是配置下虚拟站点的文件
ScriptAlias /var/www/cgi-bin/ “/var/www/cgi-bin/”
AllowOverride None
Options +ExecCGI -MultiViews +SymLinksIfOwnerMatch
Order allow,deny
Allow from all
AddHandler cgi-script .cgi .pl
这个是我的虚拟站点的CGI的配置内容
对了注意要改下文件夹的权限755
编写CGI程序和”常规”程序之间有两个主要的不同。
首先,在CGI程序的所有输出前面必须有一个HTTP的MIME类型的头,对客户端指明所接收内容的类型,大多数情况下,像这样:
其次,输出要求是HTML形式的,或者是浏览器可以显示的其他某种形式。多数情况下,输出是HTML形式的,但偶然也会输出一个gif图片或者其他非HTML的内容。
除了这两点,编写CGI程序和编写其他程序大致相同。
如下:
#!/usr/bin/perl
print “Content-type: text/html/n/n”;
print “Hello, World.”;
保存为test.cgi还要改下权限755我用的PERL所以要主义安装PERL的解释器
输入localhost/cgi-bin/test.cgi
就可以看见运行结果了
Hello, World
很简单不是吗!
使用浏览器从网络访问CGI程序,可能会发生四种情况:
- CGI程序的输出
- 太好了!这说明一切正常。如果输出正常但是浏览器处理出错,请确认你在CGI程序中使用了正确的 Content-Type 。
- CGI程序的源代码或者一个”POST Method Not Allowed”消息
- 这说明Apache没有被正确配置以执行CGI程序,重新阅读配置Apache看看遗漏了什么。
- 一个以”Forbidden”开头的消息
- 这说明有权限问题。参考Apache错误日志和下面的文件权限。
- 一个”Internal Server Error”消息
- 查阅Apache错误日志,可以找到CGI程序产生的出错消息”Premature end of script headers”。对此,需要检查下列各项,以找出不能产生正确HTTP头的原因。
记住,服务器不是以你的用户身份运行的,在服务器启动后,拥有的是一个非特权用户的权限(通常是nobody或www)而需要更大的权限以允许文件的执行。通常,给予nobody足够的权限以执行文件的方法是,对文件赋予任何人皆可执行的权限:
另外,如果需要对其他文件进行读取或写入,也必须对这些文件赋予正确的权限。
路径信息和环境变量当你在命令行执行一个程序,某些信息会自动传给shell而无须你操心,比如PATH ,告诉shell你所引用的文件可以在哪儿找到。
但是,在CGI程序通过web服务器执行时,则没有此PATH ,所以,你在CGI程序中引用的任何程序(如sendmail)都必须指定其完整的路径,使shell能找到它们以执行你的CGI程序。
一种普通的用法是,在CGI程序的第一行中指明解释器(通常是perl),形如:
必须保证它的确指向解释器。
另外,如果CGI程序依赖于某些环境变量,你要确保所需要的变量已经正确的由Apache进行了传递。
程序错误多数CGI程序失败的原因在于程序本身有问题,尤其是在已经消除上述两种错误而CGI挂起的情况下。在用浏览器测试以前,先在命令行中执行你的程序,能够发现大多数的问题。比如:
cd /usr/local/apache2/cgi-bin
./first.pl
(不要调用perl解释程序,因为shell和Apache会根据脚本第一行的路径信息找到解释器)
你最先看到的输出内容应当是一组HTTP头,包括Content-Type和结尾的空行。如果你看到了别的什么东西,那么当你在服务器上试运行时,Apache会返回 Premature end of script headers 错误。参见上面的编写CGI程序以获得更多信息。
错误日志错误日志是你的朋友。任何错误都会在错误日志中有所记载,所以你应该首先查看它。如果你的网站空间提供者不允许访问错误日志,那么你应该考虑换一个空间提供者。学会阅读错误日志,可以快速找出问题并快速解决。
Suexecsuexec允许CGI程序根据其所在虚拟主机或用户宿主目录的不同而以不同的用户权限运行。suexec有极其严格的权限校验,任何校验失败都会使CGI程序遭遇 Premature end of script headers 错误。
为了检查你是否使用了suexec ,运行 apachectl -V 并检查SUEXEC_BIN的位置。如果Apache在启动时发现suexec二进制文件正存在于此,那么suexec将会被激活。
除非你很精通suexec,否则请不要使用它。要禁用它,只要删除(或重命名)SUEXEC_BIN所指定位置的suexec二进制文件并重启服务器就可以了。如果你又想启用它,请首先阅读suexec文档以详细了解其运行机制,然后运行 suexec -V 命令找到suexec日志文件,并使用该日志文件找到你违反了哪条判断规则。