Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | |
Denys Vlasenko | 5d27cb3 | 2016-12-22 15:33:11 +0100 | [diff] [blame] | 3 | # post_upload.htm example: |
| 4 | # <html> |
| 5 | # <body> |
| 6 | # <form action=/cgi-bin/httpd_post_upload.cgi method=post enctype=multipart/form-data> |
| 7 | # File to upload: <input type=file name=file1> <input type=submit> |
| 8 | # </form> |
| 9 | |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 10 | # POST upload format: |
| 11 | # -----------------------------29995809218093749221856446032^M |
| 12 | # Content-Disposition: form-data; name="file1"; filename="..."^M |
| 13 | # Content-Type: application/octet-stream^M |
| 14 | # ^M <--------- headers end with empty line |
| 15 | # file contents |
| 16 | # file contents |
| 17 | # file contents |
| 18 | # ^M <--------- extra empty line |
| 19 | # -----------------------------29995809218093749221856446032--^M |
| 20 | |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 21 | file=/tmp/$$-$RANDOM |
| 22 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 23 | CR=`printf '\r'` |
| 24 | |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 25 | # CGI output must start with at least empty line (or headers) |
| 26 | printf '\r\n' |
| 27 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 28 | IFS="$CR" |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 29 | read -r delim_line |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 30 | IFS="" |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 31 | |
| 32 | while read -r line; do |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 33 | test x"$line" = x"" && break |
| 34 | test x"$line" = x"$CR" && break |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 35 | done |
| 36 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 37 | cat >"$file" |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 38 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 39 | # We need to delete the tail of "\r\ndelim_line--\r\n" |
| 40 | tail_len=$((${#delim_line} + 6)) |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 41 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 42 | # Get and check file size |
| 43 | filesize=`stat -c"%s" "$file"` |
| 44 | test "$filesize" -lt "$tail_len" && exit 1 |
Denis Vlasenko | 250aa5b | 2008-04-17 12:35:09 +0000 | [diff] [blame] | 45 | |
Denys Vlasenko | e3600a0 | 2009-11-13 09:37:50 +0100 | [diff] [blame] | 46 | # Check that tail is correct |
| 47 | dd if="$file" skip=$((filesize - tail_len)) bs=1 count=1000 >"$file.tail" 2>/dev/null |
| 48 | printf "\r\n%s--\r\n" "$delim_line" >"$file.tail.expected" |
| 49 | if ! diff -q "$file.tail" "$file.tail.expected" >/dev/null; then |
| 50 | printf "<html>\n<body>\nMalformed file upload" |
| 51 | exit 1 |
| 52 | fi |
| 53 | rm "$file.tail" |
| 54 | rm "$file.tail.expected" |
| 55 | |
| 56 | # Truncate the file |
| 57 | dd of="$file" seek=$((filesize - tail_len)) bs=1 count=0 >/dev/null 2>/dev/null |
| 58 | |
| 59 | printf "<html>\n<body>\nFile upload has been accepted" |