11#! /usr/bin/env bash
22
33declare -A HTTP_HEADERS
4+ declare -A FILE_UPLOADS
5+ declare -A FILE_UPLOAD_TYPES
6+ declare -A FILE_UPLOAD_NAMES
47declare -A QUERY_PARAMS
58declare -A FORM_DATA
69declare -A COOKIES
@@ -9,6 +12,12 @@ debug() {
912 printf " %s\n" " $@ " 1>&2
1013}
1114
15+ trim_quotes () {
16+ # Usage: trim_quotes "string"
17+ : " ${1// \' } "
18+ printf ' %s\n' " ${_// \" } "
19+ }
20+
1221urlencode () {
1322 # Usage: urlencode "string"
1423 local LC_ALL=C
172181 if [[ ${HTTP_HEADERS["Content-Type"]} == " multipart/form-data; " * ]]; then
173182 BOUNDARY=" ${HTTP_HEADERS["Content-Type"]} "
174183 BOUNDARY=" ${BOUNDARY#* =} "
175- debug " BOUNDARY=$BOUNDARY "
176184 fi
177185
178186
@@ -185,11 +193,14 @@ ${HTTP_HEADERS["Cookie"]};
185193EOF
186194 fi
187195
196+ CLEN=${HTTP_HEADERS["Content-Length"]}
197+
188198 # Read multipart body
189199 if [[ ! -z " $BOUNDARY " ]]; then
190200 state=" start"
191201 reader=" reading"
192202 local -A MULTIPART_HEADERS
203+ local -A DISPOSITIONS
193204 while read -n2 byte; do
194205 # we have to implement our own readline because of reasons
195206 if [[ " $reader " == " reading" ]]; then
206217 if [[ " $state " == " start" ]] && [[ " $PARSED " == " --$BOUNDARY " * ]]; then
207218 state=" headers"
208219 MULTIPART_HEADERS=()
220+ DISPOSITIONS=()
209221 elif [[ " $state " == " headers" ]]; then
210222 PARSED=" ${PARSED%% $' \r ' } "
211223 if [[ -z " $PARSED " ]]; then
@@ -220,11 +232,24 @@ EOF
220232 echo -n " ${line} 00" | xxd -r -p >> " $UPLOAD_TO "
221233 else
222234 # this is a newline char
223- if [[ " $PARSED " == " --$BOUNDARY --" * ]]; then
224- # sadly, we cannot goto
225- break
226- elif [[ " $PARSED " == " --$BOUNDARY " * ]]; then
235+ if [[ " $PARSED " == " --$BOUNDARY " * ]]; then
236+ while read -r -d ' ;' line; do
237+ DISPOSITIONS[" ${line%% =* } " ]=$( urldecode " ${line#* =} " )
238+ done << EOF
239+ ${MULTIPART_HEADERS["Content-Disposition"]} ;
240+ EOF
241+ NAME=$( trim_quotes " ${DISPOSITIONS[name]} " )
242+ FILENAME=$( trim_quotes " ${DISPOSITIONS[filename]} " )
243+ FILE_UPLOADS[" $NAME " ]=" $UPLOAD_TO "
244+ FILE_UPLOAD_NAMES[" $NAME " ]=" $FILENAME "
245+ FILE_UPLOAD_TYPES[" $NAME " ]=" ${MULTIPART_HEADERS[Content-Type]} "
246+ MULTIPART_HEADERS=()
247+ DISPOSITIONS=()
227248 state=" headers"
249+ if [[ " $PARSED " == " --$BOUNDARY --" * ]]; then
250+ # i dont know how, but we made it out alive
251+ break
252+ fi
228253 else
229254 echo -n " ${line} 0a" | xxd -r -p >> " $UPLOAD_TO "
230255 fi
234259 line=' '
235260 fi
236261 # wheeeeeeeeeeeeeeeee
237- done < <( stdbuf -o0 -i0 hexdump -v -e ' /1 "%02x"' )
262+ done < <( stdbuf -o0 -i0 hexdump -v -e ' /1 "%02x"' -n $CLEN )
238263 else
239264 # Read body
240- CLEN=${HTTP_HEADERS["Content-Length"]}
241265 [[ " $CLEN " =~ ^[0-9]+$ ]] && \
242266 test $CLEN -gt 0 && read -rN $CLEN REQUEST_BODY;
243267 fi
0 commit comments