Skip to content

Instantly share code, notes, and snippets.

@k0pernikus
Last active September 8, 2025 14:11
Show Gist options
  • Select an option

  • Save k0pernikus/6120e70c44f3cf2e6cf7f2c501507e0c to your computer and use it in GitHub Desktop.

Select an option

Save k0pernikus/6120e70c44f3cf2e6cf7f2c501507e0c to your computer and use it in GitHub Desktop.
wget with sanity content-length check
#!/usr/bin/env bash
set -euo pipefail
usage() {
echo "Usage: $0 -u <URL> -p <path>" >&2
echo " -u URL of the file to download." >&2
echo " -p Local path and filename to save the file as." >&2
return 1
}
url=""
path=""
while getopts "u:p:" opt; do
case "${opt}" in
u)
url="${OPTARG}"
;;
p)
path="${OPTARG}"
;;
*)
usage
exit 1
;;
esac
done
if [[ -z "$url" || -z "$path" ]]; then
usage
exit 1
fi
if ! server_response=$(wget --spider -nv --server-response "$url" 2>&1); then
echo "[ERROR] Could not retrieve server response for verification." >&2
exit 1
fi
size=$(echo "$server_response" | grep -i 'Content-Length' | awk '{print $2}' | tr -d '\r')
if [[ -z "$size" ]]; then
echo "[ERROR] Could not determine Content-Length from server." >&2
exit 1
fi
temp_path="/tmp/$(basename "$path")"
if ! wget -O "$temp_path" "$url"; then
echo "[ERROR] The download failed." >&2
exit 1
fi
if ! downloaded_size=$(stat -c%s "$temp_path" 2>/dev/null); then
echo "[ERROR] Downloaded file not found or empty." >&2
exit 1
fi
if [[ "$size" -ne "$downloaded_size" ]]; then
echo "[Error] File size mismatch: Expected $size bytes, but got $downloaded_size bytes. Download may be incomplete." >&2
rm -f "$temp_path"
exit 1
fi
echo "[INFO] expected filesize $size bytes matches"
mv "$temp_path" "$path" && echo "[INFO] moved '$temp_path' to '$path'";
echo "[SUCCESS] download finished"
exit 0
$ ./download.sh -u https://getsamplefiles.com/download/txt/sample-2.txt -p my_sample.tx
--2025-09-08 16:10:57-- https://getsamplefiles.com/download/txt/sample-2.txt
Resolving getsamplefiles.com (getsamplefiles.com)... 172.67.141.191, 104.21.9.51, 2606:4700:3033::6815:933, ...
Connecting to getsamplefiles.com (getsamplefiles.com)|172.67.141.191|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1520 (1.5K) [text/plain]
Saving to: ‘/tmp/my_sample.tx’
/tmp/my_sample.tx 100%[=====================================================================================================>] 1.48K --.-KB/s in 0s
2025-09-08 16:10:57 (18.3 MB/s) - ‘/tmp/my_sample.tx’ saved [1520/1520]
[INFO] expected filesize 1520 bytes matches
[INFO] moved '/tmp/my_sample.tx' to 'my_sample.tx'
[SUCCESS] download finished
$ bash -x ./download.sh -u https://getsamplefiles.com/download/txt/sample-2.txt -p my_sample.tx
+ set -euo pipefail
+ url=
+ path=
+ getopts u:p: opt
+ case "${opt}" in
+ url=https://getsamplefiles.com/download/txt/sample-2.txt
+ getopts u:p: opt
+ case "${opt}" in
+ path=my_sample.tx
+ getopts u:p: opt
+ [[ -z https://getsamplefiles.com/download/txt/sample-2.txt ]]
+ [[ -z my_sample.tx ]]
++ wget --spider -nv --server-response https://getsamplefiles.com/download/txt/sample-2.txt
+ server_response=' HTTP/1.1 200 OK
Date: Mon, 08 Sep 2025 14:10:44 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 1520
Connection: keep-alive
Server: cloudflare
Cache-Control: public, max-age=14400
Last-Modified: Sat, 31 Dec 2022 13:31:02 GMT
Content-Disposition: attachment; filename=sample-2.txt
Accept-Ranges: bytes
Access-Control-Allow-Methods: GET,OPTIONS,POST
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Age: 854
cf-cache-status: HIT
Vary: accept-encoding
Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=SIBCqyk%2FhDQJOrFNhqMCEHDCBlIP1VtgdjfDbHM%2BRL4nyirRyc3YMvQgvJ96E9xxgB7lRLQj3hKm98Bc%2BLF1ab3xaE6SWxRGLgptvXs9M6wqWA%3D%3D"}]}
Nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
CF-RAY: 97bf07f17850ef5b-ZRH
alt-svc: h3=":443"; ma=86400
2025-09-08 16:10:44 URL: https://getsamplefiles.com/download/txt/sample-2.txt 200 OK'
++ echo ' HTTP/1.1 200 OK
Date: Mon, 08 Sep 2025 14:10:44 GMT
Content-Type: text/plain; charset=UTF-8
Content-Length: 1520
Connection: keep-alive
Server: cloudflare
Cache-Control: public, max-age=14400
Last-Modified: Sat, 31 Dec 2022 13:31:02 GMT
Content-Disposition: attachment; filename=sample-2.txt
Accept-Ranges: bytes
Access-Control-Allow-Methods: GET,OPTIONS,POST
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
Access-Control-Allow-Origin: *
Age: 854
cf-cache-status: HIT
Vary: accept-encoding
Report-To: {"group":"cf-nel","max_age":604800,"endpoints":[{"url":"https://a.nel.cloudflare.com/report/v4?s=SIBCqyk%2FhDQJOrFNhqMCEHDCBlIP1VtgdjfDbHM%2BRL4nyirRyc3YMvQgvJ96E9xxgB7lRLQj3hKm98Bc%2BLF1ab3xaE6SWxRGLgptvXs9M6wqWA%3D%3D"}]}
Nel: {"report_to":"cf-nel","success_fraction":0.0,"max_age":604800}
CF-RAY: 97bf07f17850ef5b-ZRH
alt-svc: h3=":443"; ma=86400
2025-09-08 16:10:44 URL: https://getsamplefiles.com/download/txt/sample-2.txt 200 OK'
++ grep -i Content-Length
++ awk '{print $2}'
++ tr -d '\r'
+ size=1520
+ [[ -z 1520 ]]
++ basename my_sample.tx
+ temp_path=/tmp/my_sample.tx
+ wget -O /tmp/my_sample.tx https://getsamplefiles.com/download/txt/sample-2.txt
--2025-09-08 16:10:44-- https://getsamplefiles.com/download/txt/sample-2.txt
Resolving getsamplefiles.com (getsamplefiles.com)... 172.67.141.191, 104.21.9.51, 2606:4700:3033::6815:933, ...
Connecting to getsamplefiles.com (getsamplefiles.com)|172.67.141.191|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 1520 (1.5K) [text/plain]
Saving to: ‘/tmp/my_sample.tx’
/tmp/my_sample.tx 100%[=====================================================================================================>] 1.48K --.-KB/s in 0s
2025-09-08 16:10:44 (18.0 MB/s) - ‘/tmp/my_sample.tx’ saved [1520/1520]
++ stat -c%s /tmp/my_sample.tx
+ downloaded_size=1520
+ [[ 1520 -ne 1520 ]]
+ echo '[INFO] expected filesize 1520 bytes matches'
[INFO] expected filesize 1520 bytes matches
+ mv /tmp/my_sample.tx my_sample.tx
+ echo '[INFO] moved '\''/tmp/my_sample.tx'\'' to '\''my_sample.tx'\'''
[INFO] moved '/tmp/my_sample.tx' to 'my_sample.tx'
+ echo '[SUCCESS] download finished'
[SUCCESS] download finished
+ exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment