slitaz-base-files view rootfs/usr/lib/slitaz/httphelper.sh @ rev 281

httphelper.sh: add --skip-post (to not eat stdin)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Jul 28 12:39:15 2015 +0200 (2015-07-28)
parents efac6599349a
children d9e8cd5b9ad8
line source
1 #!/bin/sh
2 #
3 # SliTaz Helper for SHell CGI scripts - See httphelper function
4 #
5 # This helper is used in TazPanel, Pizza and other SliTaz CGI tools and
6 # services. The goal is to maintain it according to the needs of the
7 # project and Busybox httpd server applet since it is used for URL
8 # [en|de]coding.
9 #
10 # Documentation: man httphelper or /usr/share/doc/slitaz/httphelper.txt
11 #
12 # Copyright (C) SliTaz 2014-2015 - GNU GPL v2
13 #
16 alias urlencode='busybox httpd -e'
17 alias urldecode='busybox httpd -d'
20 # Send headers.
22 header() {
23 local i
24 [ -z "$1" ] && set -- "Content-type: text/html; charset=UTF-8"
25 for i in "$@" ""; do
26 echo -e "$i\r"
27 done
28 }
31 http_urlencode() {
32 sed \
33 -e "s|%|%25|g; s|!|%21|g; s|\*|%2A|g; s|'|%27|g; s|(|%28|g" \
34 -e "s|)|%29|g; s|;|%3B|g; s|:|%3A|g; s|@|%40|g; s|&|%26|g" \
35 -e "s|=|%3D|g; s|+|%2B|g; s|\$|%24|g; s|,|%2C|g; s|/|%2F|g" \
36 -e "s|\?|%3F|g; s|#|%25|g; s|\[|%5B|g; s|\]|%5D|g; s| |+|g"
37 }
40 htmlentities() {
41 echo $1 | sed \
42 -e 's|&|\&amp;|g; s|<|\&lt;|g; s|>|\&gt;|g' \
43 -e 's|"|\&quot;|g; s|'"'"'|\&apos;|g; s|\t|\&#09;|g'
44 }
47 # MD5 crypt a string such as password (httpd -m give not the same result)
49 md5crypt() {
50 echo -n "$1" | md5sum | awk '{print $1}'
51 }
54 # MD5 crypt a string. Stronger crypto than MD5
56 sha512crypt() {
57 echo -n "$1" | sha512sum | awk '{print $1}'
58 }
61 _ARRAY() {
62 if [ -z "$2" ]; then
63 eval echo \$${1}__NAMES
64 else
65 [ -n "$(eval echo \$${1}__NAMES)" ] && eval "echo \"\$${1}_${2}_${3:-1}\""
66 fi
67 }
70 GET() { _ARRAY GET "$1" $2; }
71 POST() { _ARRAY POST "$1" $2; }
72 FILE() { _ARRAY FILE "$1" $2; }
73 COOKIE() { _ARRAY COOKIE "$1" $2; }
76 httpinfo() {
77 local i
78 local j
79 local x
80 env | sort | sed "s/=/='/;s/$/'/"
81 for x in GET POST COOKIE ; do
82 for i in $($x) ; do
83 if [ $($x $i count) -gt 1 ]; then
84 for j in $(seq 1 $($x $i count)); do
85 echo "$x($i,$j)='$($x $i $j)'"
86 done
87 else
88 echo "$x($i)='$($x $i)'"
89 fi
90 done
91 done
92 for i in $(FILE) ; do
93 for j in name size type tmpname ; do
94 echo "FILE($i,$j)='$(FILE $i $j)'"
95 done
96 done
97 }
100 read_query_string() {
101 local i
102 local names
103 local cnt
104 names=""
105 IFS="&"
106 for i in $2; do
107 var=${i%%=*}
108 case " $names " in
109 *\ $var\ *)
110 eval cnt=\$${1}_${var}_count ;;
111 *)
112 cnt=0
113 names="$names $var" ;;
114 esac
115 eval ${1}_${var}_count=$((++cnt))
116 eval "${1}_${var}_$cnt='$(busybox httpd -d "${i#*=}" | sed "s/'/\'\\\\\'\'/g; s|\r||g")'"
117 done
118 unset IFS
119 eval ${1}__NAMES=\'${names# }\'
120 }
124 [ -z "$GET__NAMES" ] && read_query_string GET "$QUERY_STRING"
125 [ -z "$COOKIE_NAMES" ] &&
126 read_query_string COOKIE "$(echo "$HTTP_COOKIE" | sed 's/; /\&/g')"
130 ddcut() {
131 page=4096
132 skip=$1
133 count=$(($2 - $1 -2))
135 tmp=$(($skip / $page))
136 [ $tmp -ne 0 ] && dd bs=$page skip=$tmp count=0
138 skip=$(($skip - ($tmp * $page) ))
139 dd bs=1 skip=$skip count=0
141 tmp=$(( ($page - $skip) % $page ))
142 if [ $tmp -ne 0 -a $tmp -le $count ]; then
143 dd bs=1 count=$tmp
144 count=$(($count - $tmp))
145 fi
147 tmp=$(($count / $page))
148 [ $tmp -ne 0 ] && dd bs=$page count=$tmp
149 dd bs=1 count=$(($count - ($tmp * $page) ))
150 }
153 [ "$1" == "--skip-post" ] ||
154 if [ "$REQUEST_METHOD$POST__NAMES" == "POST" ]; then
155 prefix=/tmp/httpd_post
156 mkdir $prefix$$
157 now=$(stat -c %Y $prefix$$)
158 for i in $prefix* ; do
159 [ $(stat -c %Y $i) -lt $(($now - 3600)) ] && rm -rf $i
160 done
161 post=$prefix$$/post
162 n=1
163 cat > ${post}0
164 read args < ${post}0
165 delim="${args%?}"
167 case "$delim" in
169 -*)
170 awk "/$delim/ { o+=index(\$0,\"$delim\")-1; print o }
171 { o+=1+length() }" < ${post}0 | \
172 while read offset; do
173 if [ $offset -ne 0 ]; then
174 ddcut $last $offset < ${post}0 > $post$n 2> /dev/null
175 n=$(($n+1))
176 fi
177 last=$offset
178 done
179 rm -f ${post}0
181 for i in $post* ; do
182 head -n2 $i | grep -q filename= || echo '' >> $i
183 filename=
184 while read line; do
185 case "$line" in
187 *Content-Disposition*)
188 name=$(echo $line | sed 's/.* name="\([^"]*\)".*$/\1/')
189 name=${name%%[^A-Za-z_0-9]*}
190 case "$line" in
191 *filename=*)
192 filename=$(echo $line | sed 's/.* filename="\([^"]*\)".*$/\1/') ;;
193 esac ;;
195 *Content-Type*)
196 type=$(echo $line | sed 's/.*-Type: \(.*\).$/\1/') ;;
198 $'\r')
199 if [ -n "$filename" ]; then
200 tmp=$(mktemp $prefix$$/uploadXXXXXX)
201 cat > $tmp
202 FILE__NAMES="$FILE__NAMES $name"
203 FILE__NAMES="${FILE__NAMES# }"
204 eval FILE_${name}_tmpname=$tmp
205 eval FILE_${name}_name=$filename
206 eval FILE_${name}_size=$(stat -c %s $tmp)
207 eval FILE_${name}_type=$type
208 elif [ -n "$name" ]; then
209 eval cnt=\$POST_${name}_count
210 cnt=$(($cnt + 1))
211 eval var=\$POST_${name}_$cnt
212 while read line; do
213 [ -n "$var" ] && var="$var"$'\n'
214 var="$var$line"
215 done
216 eval POST_${name}_$cnt="\$var"
217 eval POST_${name}_count=$cnt
218 case " $POST__NAMES " in
219 *\ $name\ *)
220 ;;
221 *)
222 POST__NAMES="$POST__NAMES $name"
223 POST__NAMES="${POST__NAMES# }" ;;
224 esac
225 fi
226 break ;;
228 *) ;;
229 esac
230 done < $i
231 rm -f $i
232 done
233 #rmdir $(dirname $post)
234 ;;
236 *)
237 rm -rf $(dirname $post)
238 read_query_string POST "$args" ;;
240 esac
241 fi