Skip to content
This repository has been archived by the owner on Nov 3, 2021. It is now read-only.

Commit

Permalink
httpd_post_upload.txt example: handle binary files too
Browse files Browse the repository at this point in the history
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
  • Loading branch information
Denys Vlasenko committed Nov 13, 2009
1 parent 5799248 commit e3600a0
Showing 1 changed file with 26 additions and 37 deletions.
63 changes: 26 additions & 37 deletions networking/httpd_post_upload.txt
Expand Up @@ -24,53 +24,42 @@ post_upload.cgi
# ^M <--------- extra empty line
# -----------------------------29995809218093749221856446032--^M

# Beware: bashism $'\r' is used to handle ^M

file=/tmp/$$-$RANDOM

CR=`printf '\r'`

# CGI output must start with at least empty line (or headers)
printf '\r\n'

IFS=$'\r'
IFS="$CR"
read -r delim_line

IFS=''
delim_line="${delim_line}--"$'\r'
IFS=""

while read -r line; do
test "$line" = '' && break
test "$line" = $'\r' && break
test x"$line" = x"" && break
test x"$line" = x"$CR" && break
done

# This will not work well for binary files: bash 3.2 is upset
# by reading NUL bytes and loses chunks of data.
# If you are not bothered by having junk appended to the uploaded file,
# consider using simple "cat >file" instead of the entire
# fragment below.
cat >"$file"

while read -r line; do
# We need to delete the tail of "\r\ndelim_line--\r\n"
tail_len=$((${#delim_line} + 6))

while test "$line" = $'\r'; do
read -r line
test "$line" = "$delim_line" && {
# Aha! Empty line + delimiter! All done
cat <<EOF
<html>
<body>
File upload has been accepted
EOF
exit 0
}
# Empty line + NOT delimiter. Save empty line,
# and go check next line
printf "%s\n" $'\r' >&3
done
# Not empty line - just save
printf "%s\n" "$line" >&3
done 3>"$file"
# Get and check file size
filesize=`stat -c"%s" "$file"`
test "$filesize" -lt "$tail_len" && exit 1

cat <<EOF
<html>
<body>
File upload was not terminated with '$delim_line' - ??!
EOF
# Check that tail is correct
dd if="$file" skip=$((filesize - tail_len)) bs=1 count=1000 >"$file.tail" 2>/dev/null
printf "\r\n%s--\r\n" "$delim_line" >"$file.tail.expected"
if ! diff -q "$file.tail" "$file.tail.expected" >/dev/null; then
printf "<html>\n<body>\nMalformed file upload"
exit 1
fi
rm "$file.tail"
rm "$file.tail.expected"

# Truncate the file
dd of="$file" seek=$((filesize - tail_len)) bs=1 count=0 >/dev/null 2>/dev/null

printf "<html>\n<body>\nFile upload has been accepted"

0 comments on commit e3600a0

Please sign in to comment.