一個解析cgi參數的SHELL腳本

http://www.cnblogs.com/mfryf/archive/2012/05/23/2514495.htmlhtml

測試工做中,常常會涉及到一些要驗證服務器對某些cgi接口查詢結果返回信息進行解析是否正確的狀況。而提供cgi接口的一般又是另外的部門,測試的時候須要調試一些返回結果不方便。因此須要本身模擬虛假的cgi接口來達到一樣的目的。web

      好比說,相似http://www.yousite.com/query.cgi?username=***&kind=***這樣的接口會根據username和kind的值的不一樣返回6類結果,每一類結果,請求服務器都會針對地走不一樣的處理流程,這就須要每個返回結果都須要模擬到,因而乎,創建模擬的cgi接口勢在必行。之前本身也沒有接觸過cgi程序,翻了一些基礎資料發現整體框架也不是很複雜,而解析html發過來的參數有很多現成的程序可使用,不用本身寫了。由於只是須要簡單的模擬返回結果,因此用shell寫cgi程序,開始用了uncgi解析,配置很方便,具體方法能夠看:shell

http://www.midwinter.com/~koreth/uncgi.html服務器

 

後來又發現一個shell寫的解析程序proccgi.sh,彷佛在簡單的cgi接口中使用更方便app

 

 

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.            fp@informatik.uni-frankfurt.de
#
# 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
 fiide

 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)
#this

 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=""
 fispa

 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
#
# done.
#
exit 0

 

 

  使用方法:

       在本身的cgi腳本中直接調用這個shell解析參數便可,如:

       eval `proccgi.sh $*`        # 能夠把proccgi.sh放在你服務器的cgi-bin目錄

      若是上面的調用出錯,嘗試用絕對路徑調用  eval `/home/www/cgi-bin/proccgi.sh $*`

 

 

      例子,好比有一個cgi接口,按照下面的參數調用:

      http://your-website/cgi-bin/mycript?username=your_name&password=mypass

      返回結果:

      your_name

      mypass

 

    則,mycript的內容爲:

 

#!/bin/sh

eval `/home/www/cgi-bin/proccgi.sh $*`

echo Content-type: text/plain

echo

echo $FORM_username

echo $FORM_password

 

 

 

 

  

      參數裏面每一對key/value存儲在$FORM_key 環境變量裏面。
 

順便貼一下cgi-bin目錄的通用配置

 

 

 

 

        ScriptAlias /cgi-bin/ /home/www/c

相關文章
相關標籤/搜索