wok-stable annotate busybox/stuff/httpd_helper.sh @ rev 9596

busybox/httpd_helper.sh: add POST & GET arrays support
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Apr 13 11:06:30 2011 +0200 (2011-04-13)
parents f24a58320b67
children b0437daaa419
rev   line source
pascal@5685 1 #!/bin/sh
pascal@5685 2 #
pascal@5685 3 # busybox/httpd helper for shell cgi scripts
pascal@5685 4 #
pascal@5685 5 # GET [var] | POST [var] | FILE [var {name|tmpname|size|type}]
pascal@5685 6 # urlencode string | htmlentities string | httpinfo
pascal@5685 7
pascal@5685 8 alias urlencode='httpd -e'
pascal@5685 9
pascal@9514 10 # Send headers, example :
pascal@9514 11 # header "Content-type: text/html" "Set-Cookie: name=value; HttpOnly"
pascal@5685 12 header()
pascal@5685 13 {
pascal@9514 14 [ -z "$1" ] && set -- "Content-type: text/html"
pascal@9514 15 for i in "$@" "" ; do echo -e "$i\r"; done
pascal@5685 16 }
pascal@5685 17
pascal@5685 18 htmlentities()
pascal@5685 19 {
pascal@9454 20 echo $1 | sed 's|&|\&amp;|g;s|<|\&lt;|g;s|>|\&gt;|g;s|"|\&quot;|g'
pascal@5685 21 }
pascal@5685 22
pascal@5685 23 GET()
pascal@5685 24 {
pascal@9596 25 local n
pascal@9596 26 n=$2
pascal@9596 27 [ -n "$n" ] || n=1
pascal@9596 28 [ -z "$1" ] && echo $GET__NAMES ||
pascal@9596 29 [ -n "$GET__NAMES" ] && eval echo \$GET_${1}_$n
pascal@5685 30 }
pascal@5685 31
pascal@5685 32 POST()
pascal@5685 33 {
pascal@9596 34 local n
pascal@9596 35 n=$2
pascal@9596 36 [ -n "$n" ] || n=1
pascal@9596 37 [ -z "$1" ] && echo $POST__NAMES ||
pascal@9596 38 [ -n "$POST__NAMES" ] && eval echo \$POST_${1}_$n
pascal@5685 39 }
pascal@5685 40
pascal@5685 41 FILE()
pascal@5685 42 {
pascal@9596 43 [ -z "$1" ] && echo $FILE__NAMES || [ -n "$FILE__NAMES" ] && eval echo \$FILE_${1}_$2
pascal@5685 44 }
pascal@5685 45
pascal@5685 46 httpinfo()
pascal@5685 47 {
pascal@5685 48 local i
pascal@5685 49 local x
pascal@5685 50 for i in SERVER_PROTOCOL SERVER_SOFTWARE SERVER_NAME SERVER_PORT AUTH_TYPE \
pascal@5773 51 GATEWAY_INTERFACE REMOTE_HOST REMOTE_ADDR REMOTE_PORT \
pascal@5773 52 HTTP_REFERER HTTP_HOST HTTP_USER_AGENT HTTP_ACCEPT \
pascal@5773 53 HTTP_ACCEPT_LANGUAGE HTTP_COOKIE AUTH_TYPE REMOTE_USER REMOTE_IDENT \
pascal@5685 54 REQUEST_METHOD REQUEST_URI QUERY_STRING CONTENT_LENGTH CONTENT_TYPE \
pascal@5773 55 SCRIPT_NAME SCRIPT_FILENAME PATH_INFO PATH_TRANSLATED \
pascal@5773 56 USER HOME LOGNAME SHELL PWD ; do
pascal@5685 57 eval x=\$$i
pascal@5685 58 [ -n "$x" ] && echo "$i='$x'"
pascal@5685 59 done
pascal@5685 60 for i in $GET__NAMES ; do
pascal@9596 61 if [ $(GET $i count) -gt 1 ]; then
pascal@9596 62 for j in $(seq 1 $(GET $i count)); do
pascal@9596 63 echo "GET[$i][$j]='$(GET $i $j)'"
pascal@9596 64 done
pascal@9596 65 else
pascal@9596 66 echo "GET[$i]='$(GET $i)'"
pascal@9596 67 fi
pascal@5685 68 done
pascal@5685 69 for i in $POST__NAMES ; do
pascal@9596 70 if [ $(POST $i count) -gt 1 ]; then
pascal@9596 71 for j in $(seq 1 $(POST $i count)); do
pascal@9596 72 echo "POST[$i][$j]='$(POST $i $j)'"
pascal@9596 73 done
pascal@9596 74 else
pascal@9596 75 echo "POST[$i]='$(POST $i)'"
pascal@9596 76 fi
pascal@5685 77 done
pascal@5685 78 for i in $FILE__NAMES ; do
pascal@5685 79 for j in name size type tmpname ; do
pascal@5685 80 echo "FILE[$i][$j]='$(FILE $i $j)'"
pascal@5685 81 done
pascal@5685 82 done
pascal@5685 83 }
pascal@5685 84
pascal@5685 85 read_query_string()
pascal@5685 86 {
pascal@5685 87 local i
pascal@5685 88 local names
pascal@9596 89 local cnt
pascal@5685 90 names=""
pascal@5685 91 IFS="&"
pascal@5685 92 for i in $QUERY_STRING ; do
pascal@9596 93 var=${i%%=*}
pascal@9596 94 case " $names " in
pascal@9596 95 *\ $var\ *)
pascal@9596 96 eval cnt=\$${1}_${var}_count ;;
pascal@9596 97 *)
pascal@9596 98 cnt=0
pascal@9596 99 names="$names $var" ;;
pascal@9596 100 esac
pascal@9596 101 eval ${1}_${var}_count=$((++cnt))
pascal@9596 102 eval ${1}_${var}_$cnt=\'$(httpd -d "${i#*=}" | sed "s/'/\'\\\\\'\'/g")\'
pascal@5685 103 done
pascal@5685 104 unset IFS
pascal@5685 105 eval ${1}__NAMES=\'${names# }\'
pascal@5685 106 }
pascal@5685 107
pascal@9454 108 [ -z "$GET__NAMES" ] && read_query_string GET
pascal@5685 109
pascal@5685 110 ddcut()
pascal@5685 111 {
pascal@5685 112 page=4096
pascal@5685 113 skip=$1
pascal@5685 114 count=$(($2 - $1 -2))
pascal@5685 115 tmp=$(($skip / $page))
pascal@5685 116 [ $tmp -ne 0 ] && dd bs=$page skip=$tmp count=0
pascal@5685 117 skip=$(($skip - ($tmp * $page) ))
pascal@5685 118 dd bs=1 skip=$skip count=0
pascal@5685 119 tmp=$(( ($page - $skip) % $page ))
pascal@5685 120 if [ $tmp -ne 0 -a $tmp -le $count ]; then
pascal@5685 121 dd bs=1 count=$tmp
pascal@5685 122 count=$(($count - $tmp))
pascal@5685 123 fi
pascal@5685 124 tmp=$(($count / $page))
pascal@5685 125 [ $tmp -ne 0 ] && dd bs=$page count=$tmp
pascal@5685 126 dd bs=1 count=$(($count - ($tmp * $page) ))
pascal@5685 127 }
pascal@5685 128
pascal@9454 129 if [ "$REQUEST_METHOD$POST__NAMES" == "POST" ]; then
pascal@5685 130 prefix=/tmp/httpd_post
pascal@5685 131 mkdir $prefix$$
pascal@5685 132 now=$(stat -c %Y $prefix$$)
pascal@5685 133 for i in $prefix* ; do
pascal@5685 134 [ $(stat -c %Y $i) -lt $(($now - 3600)) ] && rm -rf $i
pascal@5685 135 done
pascal@5685 136 post=$prefix$$/post
pascal@5685 137 n=1
pascal@5685 138 cat > ${post}0
pascal@5685 139 read delim < ${post}0
pascal@5685 140 case "$delim" in
pascal@9455 141 -*) awk "/${delim%?}/ { o+=index(\$0,\"$delim\")-1; print o }
pascal@5685 142 { o+=1+length() }" < ${post}0 | while read offset; do
pascal@5685 143 if [ $offset -ne 0 ]; then
pascal@5685 144 ddcut $last $offset < ${post}0 > $post$n 2> /dev/null
pascal@5685 145 n=$(($n+1))
pascal@5685 146 fi
pascal@5685 147 last=$offset
pascal@5685 148 done
pascal@5685 149 rm -f ${post}0
pascal@5685 150 CR=`printf '\r'`
pascal@5685 151 for i in $post* ; do
pascal@5685 152 head -n 2 $i | grep -q filename= || echo '' >> $i
pascal@5685 153 filename=
pascal@5685 154 while read line; do
pascal@5685 155 case "$line" in
pascal@5685 156 *Content-Disposition*)
pascal@5685 157 name=$(echo $line | sed 's/.* name="\([^"]*\)".*$/\1/')
pascal@5685 158 case "$line" in
pascal@5685 159 *filename=*) filename=$(echo $line | sed 's/.* filename="\([^"]*\)".*$/\1/') ;;
pascal@5685 160 esac ;;
pascal@5685 161 *Content-Type*)
pascal@5685 162 type=$(echo $line | sed 's/.*-Type: \(.*\).$/\1/') ;;
pascal@5685 163 $CR)
pascal@5685 164 if [ -n "$filename" ]; then
pascal@5685 165 tmp=$(mktemp $prefix$$/uploadXXXXXX)
pascal@5685 166 cat > $tmp
pascal@5685 167 FILE__NAMES="$FILE__NAMES $name"
pascal@5685 168 FILE__NAMES="${FILE__NAMES# }"
pascal@5685 169 eval FILE_${name}_tmpname=$tmp
pascal@5685 170 eval FILE_${name}_name=$filename
pascal@5685 171 eval FILE_${name}_size=$(stat -c %s $tmp)
pascal@5685 172 eval FILE_${name}_type=$type
pascal@5685 173 elif [ -n "$name" ]; then
pascal@5685 174 eval var=\$POST_${name}
pascal@5685 175 while read line; do
pascal@5685 176 [ -n "$var" ] && var="$var
pascal@5685 177 "
pascal@5685 178 var="$line"
pascal@5685 179 done
pascal@5685 180 eval POST_${name}="\$var"
pascal@5685 181 case " $POST__NAMES " in
pascal@5685 182 *\ $name\ *) ;;
pascal@5685 183 *) POST__NAMES="$POST__NAMES $name"
pascal@5685 184 POST__NAMES="${POST__NAMES# }" ;;
pascal@5685 185 esac
pascal@5685 186 fi
pascal@5685 187 break ;;
pascal@5685 188 *)
pascal@5685 189 esac
pascal@5685 190 done < $i
pascal@5685 191 rm -f $i
pascal@5685 192 done
pascal@5685 193 rmdir $(dirname $post) ;;
pascal@5685 194 *) export QUERY_STRING="$delim"
pascal@5685 195 rm -rf $(dirname $post)
pascal@5685 196 read_query_string POST ;;
pascal@5685 197 esac
pascal@5685 198 fi