nixpkgs/pkgs/build-support/fetchurl/builder.sh
Eelco Dolstra c8df888858 Add a function "fetchzip"
This function downloads and unpacks a file in one fixed-output
derivation. This is primarily useful for dynamically generated zip
files, such as GitHub's /archive URLs, where the unpacked content of
the zip file doesn't change, but the zip file itself may (e.g. due to
minor changes in the compression algorithm, or changes in timestamps).

Fetchzip is implemented by extending fetchurl with a "postFetch" hook
that is executed after the file has been downloaded. This hook can
thus perform arbitrary checks or transformations on the downloaded
file.
2014-05-08 15:30:17 +02:00

132 lines
3 KiB
Bash

source $stdenv/setup
source $mirrorsFile
# Curl flags to handle redirects, not use EPSV, handle cookies for
# servers to need them during redirects, and work on SSL without a
# certificate (this isn't a security problem because we check the
# cryptographic hash of the output anyway).
curl="curl \
--location --max-redirs 20 \
--retry 3
--disable-epsv \
--cookie-jar cookies \
--insecure \
$curlOpts \
$NIX_CURL_FLAGS"
downloadedFile="$out"
if [ -n "$downloadToTemp" ]; then downloadedFile="$TMPDIR/file"; fi
tryDownload() {
local url="$1"
echo
header "trying $url"
success=
if $curl --fail "$url" --output "$downloadedFile"; then
success=1
fi
stopNest
}
finish() {
set +o noglob
runHook postFetch
stopNest
exit 0
}
tryHashedMirrors() {
if test -n "$NIX_HASHED_MIRRORS"; then
hashedMirrors="$NIX_HASHED_MIRRORS"
fi
for mirror in $hashedMirrors; do
url="$mirror/$outputHashAlgo/$outputHash"
if $curl --retry 0 --connect-timeout "${NIX_CONNECT_TIMEOUT:-15}" \
--fail --silent --show-error --head "$url" \
--write-out "%{http_code}" --output /dev/null > code 2> log; then
tryDownload "$url"
if test -n "$success"; then finish; fi
else
# Be quiet about 404 errors, which we interpret as the file
# not being present on this particular mirror.
if test "$(cat code)" != 404; then
echo "error checking the existence of $url:"
cat log
fi
fi
done
}
# URL list may contain ?. No glob expansion for that, please
set -o noglob
urls2=
for url in $urls; do
if test "${url:0:9}" != "mirror://"; then
urls2="$urls2 $url"
else
url2="${url:9}"; echo "${url2/\// }" > split; read site fileName < split
#varName="mirror_$site"
varName="$site" # !!! danger of name clash, fix this
if test -z "${!varName}"; then
echo "warning: unknown mirror:// site \`$site'"
else
# Assume that SourceForge/GNU/kernel mirrors have better
# bandwidth than nixos.org.
preferHashedMirrors=
mirrors=${!varName}
# Allow command-line override by setting NIX_MIRRORS_$site.
varName="NIX_MIRRORS_$site"
if test -n "${!varName}"; then mirrors="${!varName}"; fi
for url3 in $mirrors; do
urls2="$urls2 $url3$fileName";
done
fi
fi
done
urls="$urls2"
# Restore globbing settings
set +o noglob
if test -n "$showURLs"; then
echo "$urls" > $out
exit 0
fi
if test -n "$preferHashedMirrors"; then
tryHashedMirrors
fi
# URL list may contain ?. No glob expansion for that, please
set -o noglob
success=
for url in $urls; do
tryDownload "$url"
if test -n "$success"; then finish; fi
done
# Restore globbing settings
set +o noglob
if test -z "$preferHashedMirrors"; then
tryHashedMirrors
fi
echo "error: cannot download $name from any mirror"
exit 1