cgi简介以及一个用shell脚本写的shell例子分析

来源:互联网 发布:知微科技职友集 编辑:程序博客网 时间:2024/05/18 23:58

什么是cgi

cgi是common gateway interface的简称,这是一个用来处理http请求的接口;
由于http请求十分多样且十分复杂,web服务器不能完成这种操作,于是便利用了外部程序来处理这些请求,web服务器将参数传递给外部程序,外部程序将运行结果返回给web服务器;外部程序和web服务器的交互需要一种接口,那就是cgi接口,于是这些外部程序也叫cgi程序;
cgi程序不是某种语言的产物,而是一种接口,你既可以用c语言来实现cgi程序也可以用php,甚至是shell脚本来实现;
关系图如下:

外部程序是如何与web服务器进行交互的

cgi提供两种传递参数的方式:标准输入输出流,环境变量
这里的环境变量不同于操作系统提供的环境变量,这是web服务器和cgi接口所提供的用以向cgi程序传递一些重要的参数如(客户机的ip-$REMOTE-ADDR);
html中的post请求方法是用标准输入(stdin)来向cgi程序传递参数的,而html中的get请求方法则是通过环境变量QUERY-STRING来传递参数的;
下面是一些常见的cgi环境变量:
变量名描述CONTENT_TYPE这个环境变量的值指示所传递来的信息的MIME类型。目前,环境变量CONTENT_TYPE一般都是:application/x-www-form-urlencoded,他表示数据来自于HTML表单。CONTENT_LENGTH如果服务器与CGI程序信息的传递方式是POST,这个环境变量即使从标准输入STDIN中可以读到的有效数据的字节数。这个环境变量在读取所输入的数据时必须使用。HTTP_COOKIE客户机内的 COOKIE 内容。HTTP_USER_AGENT提供包含了版本数或其他专有数据的客户浏览器信息。PATH_INFO这个环境变量的值表示紧接在CGI程序名之后的其他路径信息。它常常作为CGI程序的参数出现。QUERY_STRING如果服务器与CGI程序信息的传递方式是GET,这个环境变量的值即使所传递的信息。这个信息经跟在CGI程序名的后面,两者中间用一个问号'?'分隔。REMOTE_ADDR这个环境变量的值是发送请求的客户机的IP地址,例如上面的192.168.1.67。这个值总是存在的。而且它是Web客户机需要提供给Web服务器的唯一标识,可以在CGI程序中用它来区分不同的Web客户机。REMOTE_HOST这个环境变量的值包含发送CGI请求的客户机的主机名。如果不支持你想查询,则无需定义此环境变量。REQUEST_METHOD提供脚本被调用的方法。对于使用 HTTP/1.0 协议的脚本,仅 GET 和 POST 有意义。SCRIPT_FILENAMECGI脚本的完整路径SCRIPT_NAMECGI脚本的的名称SERVER_NAME这是你的 WEB 服务器的主机名、别名或IP地址。SERVER_SOFTWARE这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix)

一个shell脚本写的cgi程序例子;

这个例子会用到上面写的内容,同时也有一些对shell脚本语法的解析

#!/bin/shecho "Content-type: text/plain"echo ""if [ "$REQUEST_METHOD" = "GET" ] ; then#用POST的请求方式echo GET is not expected without httpsexit                     fiecho "<html><head>"echo "</head><body>"echo "<pre>"ip=$REMOTE_ADDR#通过环境变量将客户机ip赋给ip变量OIFS="$IFS"IFS=\&                  #域分割符,作用请参考这篇博客:<a target=_blank href="http://http://blog.csdn.net/occupy8/article/details/38386985">点击打开链接</a>read user passwd inout  # 从标准输入(stdin)中读取POST过来的字段;post方式传递参数的实例IFS="$OIFS"user=${user#username=}        # 把开始的前缀'username='去掉(变量$user中是“username=具体名字”要将$user中的“username=”去掉,再赋给userpasswd=${passwd#password=}    inout=${inout#inout=}         echo "user, passwd and your ip is: $user $passwd $ip"userconf='/etc/nasuser.list'    # 用grep命令判断传递进来的参数在nasuser.list文件中‘|’是ubuntu中的管道命令作用是将结果传递给下一条指令;grepstr="grep $userconf -e $user | grep $passwd" #grep是查找命令;这句话的作用是:从nasuser.list文件中找出变量$user所在的那一行,传递给grep $password;#这条命令再从结果中查找$password;userline=`$grepstr`if [ -z "$userline" ] ; then         #-z判断$userline时候为空;不为空则说明传进来的用户和密码是正确的可以登录;echo "invalid user"       exitfiecho okecho ""     # #exitif [ ${ip:4:1}  == ":" ] ; then   # 构造ip6tables命令 iptcmd1="/sbin/ip6tables -D FORWARD  -s $ip/128 -j ACCEPT"iptcmd2="/sbin/ip6tables -I FORWARD  -s $ip/128 -j ACCEPT"iptcmd3="/sbin/ip6tables -D FORWARD  -d $ip/128 -j ACCEPT"iptcmd4="/sbin/ip6tables -I FORWARD  -d $ip/128 -j ACCEPT"else# 构造iptables命令iptcmd1="/sbin/iptables -t nat -D PREROUTING -s $ip/32 -j ACCEPT"iptcmd2="/sbin/iptables -t nat -I PREROUTING -s $ip/32 -j ACCEPT"iptcmd3="/sbin/iptables -t filter -D FORWARD -s $ip/32 -o enp0s3 -j ACCEPT"iptcmd4="/sbin/iptables -t filter -I FORWARD -s $ip/32 -o enp0s3 -j ACCEPT"fiecho 'before: ipv4'/sbin/iptables --list -n | grep all/sbin/iptables --list -n -t nat | grep allecho 'before: ipv6'/sbin/ip6tables --list -n | grep all/sbin/ip6tables --list -n -t nat | grep allecho ""echo "action:"echo $iptcmd1res=`$iptcmd1`echo $iptcmd3res=`$iptcmd3`if [ $inout == "I" ] ; thenecho $iptcmd2res=`$iptcmd2`echo $iptcmd4res=`$iptcmd4`fiecho ""echo 'after: ipv4'/sbin/iptables --list -n | grep all/sbin/iptables --list -n -t nat | grep allecho 'after: ipv6'/sbin/ip6tables --list -n | grep all/sbin/ip6tables --list -n -t nat | grep all#cat /etc/nasuser.listecho "</pre>"if [ $inout == "I" ] ; thenecho "<font color=red> <strong>如果出现某些可能的BUG,请关闭浏览器窗口并重新打开即可。</strong>"fiecho "</body></html>"exit


参考了以下两篇博客
cgi详解
cgi编程的get和post
0 0
原创粉丝点击