From 32fcc5ecca5bc81c4b7e5423920af4a0d40e07b5 Mon Sep 17 00:00:00 2001 From: Vlastimil Holer Date: Thu, 23 Nov 2017 15:36:04 +0100 Subject: [PATCH] B #1481: Avoid downloading complete file on partial download (#1513) --- src/datastore_mad/remotes/downloader.sh | 50 ++++++++++++++++++++----- 1 file changed, 40 insertions(+), 10 deletions(-) diff --git a/src/datastore_mad/remotes/downloader.sh b/src/datastore_mad/remotes/downloader.sh index 1f85dda909..285b5762ff 100755 --- a/src/datastore_mad/remotes/downloader.sh +++ b/src/datastore_mad/remotes/downloader.sh @@ -270,8 +270,13 @@ done FROM="$1" TO="$2" -# File used by the hasher function to store the resulting hash -export HASH_FILE="/tmp/downloader.hash.$$" +if [ -n "${HASH_TYPE}" -a -n "${MAX_SIZE}" ]; then + echo "Hash check not supported for partial downloads" >&2 + exit -1 +else + # File used by the hasher function to store the resulting hash + export HASH_FILE="/tmp/downloader.hash.$$" +fi GLOBAL_CURL_ARGS="--fail -sS -k -L" @@ -335,19 +340,44 @@ if [ -z "${MAX_SIZE}" ]; then eval "$command" | \ tee >( hasher $HASH_TYPE) | \ decompress "$decompressor" "$TO" -else - # ignore broken pipe - trap '' PIPE + if [ "$?" != "0" -o "$PIPESTATUS" != "0" ]; then + echo "Error copying" >&2 + exit -1 + fi +else + # Order of the 'head' command is here on purpose: + # 1. We want to download more bytes than needed to get a requested + # number of bytes on the output. Decompressor may need more + # data to decompress the stream. + # 2. Decompressor command is also misused to detect SIGPIPE error. eval "$command" | \ - tee >( hasher $HASH_TYPE) 2>/dev/null | \ decompress "$decompressor" "$TO" 2>/dev/null | \ head -c "${MAX_SIZE}" -fi -if [ "$?" != "0" -o "$PIPESTATUS" != "0" ]; then - echo "Error copying" >&2 - exit -1 + # Following table shows exit codes of each command + # in the pipe for various scenarios: + # + # ---------------------------------------------------- + # | $COMMAND | TYPE | PIPESTATUS | BEHAVIOUR + # ---------------------------------------------------- + # | cat | partial | 141 141 0 | OK + # | cat | full | 0 0 0 | OK + # | cat | error | 1 0 0 | fail + # | curl | partial | 23 141 0 | OK + # | curl | full | 0 0 0 | OK + # | curl | error | 22 0 0 | fail + # | ssh | partial | 255 141 0 | OK + # | ssh | full | 0 0 0 | OK + # | ssh | error ssh | 255 0 0 | fail + # | ssh | error ssh cat | 1 0 0 | fail + if [ \( "${PIPESTATUS[0]}" != '0' -a "${PIPESTATUS[1]}" = '0' \) \ + -o \( "${PIPESTATUS[1]}" != '0' -a "${PIPESTATUS[1]}" != '141' \) \ + -o \( "${PIPESTATUS[2]}" != "0" \) ]; + then + echo "Error copying" >&2 + exit -1 + fi fi if [ -n "$HASH_TYPE" ]; then