@@ -168,10 +168,79 @@ EOF
168168 # debug "$line"
169169 done
170170
171- # Read body
172- CLEN=${HTTP_HEADERS["Content-Length"]}
173- [[ " $CLEN " =~ ^[0-9]+$ ]] && \
174- test $CLEN -gt 0 && read -rN $CLEN REQUEST_BODY;
171+ # Parse multipart Form Data
172+ if [[ ${HTTP_HEADERS["Content-Type"]} == " multipart/form-data; " * ]]; then
173+ BOUNDARY=" ${HTTP_HEADERS["Content-Type"]} "
174+ BOUNDARY=" ${BOUNDARY#* =} "
175+ debug " BOUNDARY=$BOUNDARY "
176+ fi
177+
178+
179+ # Read cookies (yum!)
180+ if [[ ! -z " ${HTTP_HEADERS["Cookie"]} " ]]; then
181+ while read -r -d ' ;' line; do
182+ COOKIES[" ${line%% =* } " ]=$( urldecode " ${line#* =} " )
183+ done << EOF
184+ ${HTTP_HEADERS["Cookie"]} ;
185+ EOF
186+ fi
187+
188+ # Read multipart body
189+ if [[ ! -z " $BOUNDARY " ]]; then
190+ state=" start"
191+ reader=" reading"
192+ local -A MULTIPART_HEADERS
193+ while read -n2 byte; do
194+ # we have to implement our own readline because of reasons
195+ if [[ " $reader " == " reading" ]]; then
196+ if [[ " $byte " == " 0a" ]]; then
197+ reader=" flushing-newline"
198+ elif [[ " $byte " == " 00" ]]; then
199+ reader=" flushing-null"
200+ else
201+ line=" ${line}${byte} "
202+ fi
203+ fi
204+ if [[ " $reader " == " flushing" * ]]; then
205+ PARSED=" $( echo -n $line | xxd -r -p) "
206+ if [[ " $state " == " start" ]] && [[ " $PARSED " == " --$BOUNDARY " * ]]; then
207+ state=" headers"
208+ MULTIPART_HEADERS=()
209+ elif [[ " $state " == " headers" ]]; then
210+ PARSED=" ${PARSED%% $' \r ' } "
211+ if [[ -z " $PARSED " ]]; then
212+ UPLOAD_TO=$( mktemp -p uploads)
213+ state=" body"
214+ else
215+ MULTIPART_HEADERS[" ${PARSED%%:* } " ]=" ${PARSED#*: } "
216+ fi
217+ elif [[ " $state " == " body" ]]; then
218+ if [[ " $reader " == " flushing-null" ]]; then
219+ # this is a null char
220+ echo -n " ${line} 00" | xxd -r -p >> " $UPLOAD_TO "
221+ else
222+ # this is a newline char
223+ if [[ " $PARSED " == " --$BOUNDARY --" * ]]; then
224+ # sadly, we cannot goto
225+ break
226+ elif [[ " $PARSED " == " --$BOUNDARY " * ]]; then
227+ state=" headers"
228+ else
229+ echo -n " ${line} 0a" | xxd -r -p >> " $UPLOAD_TO "
230+ fi
231+ fi
232+ fi
233+ reader=" reading"
234+ line=' '
235+ fi
236+ # wheeeeeeeeeeeeeeeee
237+ done < <( stdbuf -o0 -i0 hexdump -v -e ' /1 "%02x"' )
238+ else
239+ # Read body
240+ CLEN=${HTTP_HEADERS["Content-Length"]}
241+ [[ " $CLEN " =~ ^[0-9]+$ ]] && \
242+ test $CLEN -gt 0 && read -rN $CLEN REQUEST_BODY;
243+ fi
175244 # Parse Form Data
176245 if [[ ! -z " $REQUEST_BODY " ]] && \
177246 [[ ${HTTP_HEADERS["Content-Type"]} == " application/x-www-form-urlencoded" ]]; then
@@ -182,13 +251,6 @@ ${REQUEST_BODY}&
182251EOF
183252 fi
184253
185- if [[ ! -z " ${HTTP_HEADERS["Cookie"]} " ]]; then
186- while read -r -d ' ;' line; do
187- COOKIES[" ${line%% =* } " ]=$( urldecode " ${line#* =} " )
188- done << EOF
189- ${HTTP_HEADERS["Cookie"]} ;
190- EOF
191- fi
192254}
193255
194256writeHttpResponse () {
0 commit comments