cgi简介以及一个用shell脚本写的shell例子分析
什么是cgicgi是common gateway interface的简称,这是一个用来处理http请求的接口;由于http请求十分多样且十分复杂,web服务器不能完成这种操作,于是便利用了外部程序来处理这些请求,web服务器将参数传递给外部程序,外部程序将运行结果返回给web服务器;外部程序和web服务器的交互需要一种接口,那就是cgi接口,于是这些外部程序也叫cgi程序;c
·
什么是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_FILENAME | CGI脚本的完整路径 |
SCRIPT_NAME | CGI脚本的的名称 |
SERVER_NAME | 这是你的 WEB 服务器的主机名、别名或IP地址。 |
SERVER_SOFTWARE | 这个环境变量的值包含了调用CGI程序的HTTP服务器的名称和版本号。例如,上面的值为Apache/2.2.14(Unix) |
一个shell脚本写的cgi程序例子;
这个例子会用到上面写的内容,同时也有一些对shell脚本语法的解析
#!/bin/sh
echo "Content-type: text/plain"
echo ""
if [ "$REQUEST_METHOD" = "GET" ] ; then #用POST的请求方式
echo GET is not expected without https
exit
fi
echo "<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=”去掉,再赋给user
passwd=${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"
exit
fi
echo ok
echo "" #
#exit
if [ ${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"
fi
echo 'before: ipv4'
/sbin/iptables --list -n | grep all
/sbin/iptables --list -n -t nat | grep all
echo 'before: ipv6'
/sbin/ip6tables --list -n | grep all
/sbin/ip6tables --list -n -t nat | grep all
echo ""
echo "action:"
echo $iptcmd1
res=`$iptcmd1`
echo $iptcmd3
res=`$iptcmd3`
if [ $inout == "I" ] ; then
echo $iptcmd2
res=`$iptcmd2`
echo $iptcmd4
res=`$iptcmd4`
fi
echo ""
echo 'after: ipv4'
/sbin/iptables --list -n | grep all
/sbin/iptables --list -n -t nat | grep all
echo 'after: ipv6'
/sbin/ip6tables --list -n | grep all
/sbin/ip6tables --list -n -t nat | grep all
#cat /etc/nasuser.list
echo "</pre>"
if [ $inout == "I" ] ; then
echo "<font color=red> <strong>如果出现某些可能的BUG,请关闭浏览器窗口并重新打开即可。</strong>"
fi
echo "</body></html>"
exit
参考了以下两篇博客
更多推荐
已为社区贡献1条内容
所有评论(0)