本文涉及到目前遇到的几个方面的问题,也是分享,也做个记号备忘。
1)下载: http://www.acme.com/software/thttpd/
2) 交叉编译
命令:CC=arm-linux-gcc ./configure --host=arm-linux
这里有几个问题需要注意,比较令人郁闷的事情
1,config.cache会记录上次的配置,所以一定要先删除,再配置
2,配置语句:CC=arm-linux-gcc ./configure --host=arm-linux
3,不能建立build目录,使用../configure 配置
4,编译完成后,用如下命令可启动之:
sudo ./thttpd -d /home/lfx/html/ -c /cgi-bin/\*
也可使用配置文件启动:sudo ./thttpd -C thttpd.conf
thttpd.conf中需要添加cgipat=/cgi-bin/* 以便支持cgi
cgi的路径,实际上是从配置文件的dir路径开始算的。
chroot要删除。
5,配置完成后,要得到CGI的运行结果,可以输入这样的地址:
http://192.168.12.44/cgi-bin/getdate.sh
把配置文件thttpd.conf的内容贴在这里
# This section overrides defaults dir=/home/lfx/html #chroot user=lfx# default = nobody logfile=/var/log/thttpd.log pidfile=/var/run/thttpd.pid cgipat=/cgi-bin/* charset=UTF-8 max_age=0 # This section _documents_ defaults in effect # port=80 # nosymlink# default = !chroot # novhost # nocgipat # nothrottles # host=0.0.0.0 # charset=iso-8859-1
CGI的参数传递有两种方法,一个比较简单,就是在URL后面直接跟参数,
就像这样http://192.168.12.44/cgi-bin/myscript.sh?lfx+123456
这种做法的好处是不需要解析,在服务端,会直接调用myscript.sh lfx 123
还有一种比较通用,但是稍微麻烦的格式:
http://192.168.12.44/cgi-bin/myscript.sh?username=lfx&password=123456
这种的好处是通用,几乎都是这么弄的。坏处是字符串没直接传递过来,而是放在环境变量:QUERY_STRING中。
而QUERY_STRING的值为username=lfx&password=123456
下面两个脚本,一个是工具脚本,负责解析,另一个是演示脚本
工具脚本proccgi.sh
#!/bin/sh # # Process input to a CGI script. Written and Copyright 1995 Frank Pilhofer # You may freely use and distribute this code free of charge provided that # this copyright notice remains. [email protected] # # All variables in here are prefixed by _F_, so you shouldn't have # any conflicts with your own var names # # get query string. if $REQUEST_METHOD is "POST", then it must be read # from stdin, else it's in $QUERY_STRING # if [ ${DEBUG:-0} -eq 1 ] ; then echo --Program Starts-- 1>&2 fi # if [ "$REQUEST_METHOD" = "POST" ] ; then _F_QUERY_STRING=`dd count=$CONTENT_LENGTH bs=1 2> /dev/null`"&" if [ "$QUERY_STRING" != "" ] ; then _F_QUERY_STRING="$_F_QUERY_STRING""$QUERY_STRING""&" fi if [ ${DEBUG:-0} -eq 1 ] ; then echo --Posted String-- 1>&2 fi else _F_QUERY_STRING="$QUERY_STRING""&" if [ ${DEBUG:-0} -eq 1 ] ; then echo --Query String-- 1>&2 fi fi if [ ${DEBUG:-0} -eq 1 ] ; then ( echo " " $_F_QUERY_STRING echo --Adding Arguments-- ) 1>&2 fi # # if there are arguments, use them as well. # for _F_PAR in $* ; do _F_QUERY_STRING="$_F_QUERY_STRING""$_F_PAR""&" if [ ${DEBUG:-0} -eq 1 ] ; then echo " " arg $_F_PAR 1>&2 fi done if [ ${DEBUG:-0} -eq 1 ] ; then ( echo --With Added Arguments-- echo " " $_F_QUERY_STRING ) 1>&2 fi # # if $PATH_INFO is not empty and contains definitions '=', append it as well. # but replace slashes by ampersands # if echo $PATH_INFO | grep = > /dev/null ; then _F_PATH_INFO="$PATH_INFO""//" if [ ${DEBUG:-0} -eq 1 ] ; then ( echo --Adding Path Info-- echo " " $_F_PATH_INFO ) 1>&2 fi while [ "$_F_PATH_INFO" != "" -a "$_F_PATH_INFO" != "/" ] ; do _F_QUERY_STRING="$_F_QUERY_STRING""`echo $_F_PATH_INFO | cut -d / -f 1`""&" _F_PATH_INFO=`echo $_F_PATH_INFO | cut -s -d / -f 2-` done fi # # append another '&' to fool some braindead cut implementations. Test yours: # echo 'i am braindead!' | cut -d '!' -f 2 # _F_QUERY_STRING="$_F_QUERY_STRING""&" # if [ ${DEBUG:-0} -eq 1 ] ; then ( echo --Final Query String-- echo " " $_F_QUERY_STRING ) 1>&2 fi # while [ "$_F_QUERY_STRING" != "" -a "$_F_QUERY_STRING" != "&" ] ; do _F_VARDEF=`echo $_F_QUERY_STRING | cut -d \& -f 1` # _F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-` _F_VAR=`echo $_F_VARDEF | cut -d = -f 1` _F_VAL=`echo "$_F_VARDEF""=" | cut -d = -f 2` # # Workaround for more braindead cut implementations that strip delimiters # at the end of the line (i.e. HP-UX 10) # if echo $_F_QUERY_STRING | grep -c \& > /dev/null ; then _F_QUERY_STRING=`echo $_F_QUERY_STRING | cut -d \& -f 2-` else _F_QUERY_STRING="" fi if [ ${DEBUG:-0} -eq 1 ] ; then ( echo --Got Variable-- echo " " var=$_F_VAR echo " " val=$_F_VAL echo " " rem=$_F_QUERY_STRING ) 1>&2 fi if [ "$_F_VAR" = "" ] ; then continue fi # # replace '+' by spaces # _F_VAL="$_F_VAL""++" _F_TMP= while [ "$_F_VAL" != "" -a "$_F_VAL" != "+" -a "$_F_VAL" != "++" ] ; do _F_TMP="$_F_TMP""`echo $_F_VAL | cut -d + -f 1`" _F_VAL=`echo $_F_VAL | cut -s -d + -f 2-` if [ "$_F_VAL" != "" -a "$_F_VAL" != "+" ] ; then _F_TMP="$_F_TMP"" " fi done if [ ${DEBUG:-0} -eq 1 ] ; then echo " " vrs=$_F_TMP 1>&2 fi # # replace '%XX' by ascii character. the hex sequence MUST BE uppercase # _F_TMP="$_F_TMP""%%" _F_VAL= while [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; do _F_VAL="$_F_VAL""`echo $_F_TMP | cut -d % -f 1`" _F_TMP=`echo $_F_TMP | cut -s -d % -f 2-` if [ "$_F_TMP" != "" -a "$_F_TMP" != "%" ] ; then if [ ${DEBUG:-0} -eq 1 ] ; then echo " " got hex "%" $_F_TMP 1>&2 fi _F_HEX=`echo $_F_TMP | cut -c 1-2 | tr "abcdef" "ABCDEF"` _F_TMP=`echo $_F_TMP | cut -c 3-` # # can't handle newlines anyway. replace by space # # if [ "$_F_HEX" = "0A" ] ; then # _F_HEX="20" # fi _F_VAL="$_F_VAL""`/bin/echo '\0'\`echo "16i8o"$_F_HEX"p" | dc\``" fi done # # replace forward quotes to backward quotes, since we have trouble handling # the former ones. # _F_VAL=`echo $_F_VAL | tr "'" '\`'` # # if debug, send variables to stderr # if [ ${DEBUG:-0} -eq 1 ] ; then ( echo --Final Assignment-- echo "FORM_$_F_VAR"=\'$_F_VAL\' ) 1>&2 fi # /bin/echo "FORM_$_F_VAR"=\'$_F_VAL\' /bin/echo "FORM_$_F_VAR"="'"$_F_VAL"'" done # if [ ${DEBUG:-0} -eq 1 ] ; then echo done. 1>&2 fi
测试脚本:myscript.sh
#!/bin/sh eval `./proccgi.sh $QUERY_STRING` echo Content-type: text/plain echo echo $FORM_username echo $FORM_password echo here... echo $# echo $* echo $QUERY_STRING echo echo `export`
网页的部分,为了在网页中调用URL,需要这样做:
<script> function jv_httpGet(url) { var xmlhttp; if (window.XMLHttpRequest) {// code for IE7+, Firefox, Chrome, Opera, Safari xmlhttp=new XMLHttpRequest(); } else {// code for IE6, IE5 xmlhttp=new ActiveXObject("Microsoft.XMLHTTP"); } xmlhttp.open("GET",url,false); xmlhttp.send(); return xmlhttp.responseText; } function display() { var url = http://192.168.12.44/cgi-bin/myscript.sh?lfx+123456 var ret = jv_httpGet(url); document.write(ret); } </script>
之所以要强制刷新,是因为IE在运行时,会询问服务器是否有更新,如果没有更新则不重新收数据。服务器也不重新给它发。
然而可恨的是,CGI程序本身没变,但它的运行结果却发生了变化。而服务器又以为没有变化
为解决这个问题,只好强制刷新。
修改方法,是CGI调用时,加上个东西:
function jv_httpGet(url)
{
var xmlhttp;
if (window.XMLHttpRequest)
{// code for IE7+, Firefox, Chrome, Opera, Safari
xmlhttp=new XMLHttpRequest();
}
else
{// code for IE6, IE5
xmlhttp=new ActiveXObject("Microsoft.XMLHTTP");
}
xmlhttp.open("GET",url+"+#"+new Date().getTime(),false);
xmlhttp.send();
return xmlhttp.responseText;
}
注意其中红色的部分,是比原来增加的。
对应的,服务端的程序必须处理这多出来的部分。我们用#来认为它是注释,解决掉这个问题