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