-
-
Save ansemjo/cc113ced5d133c018e95079ddb003bb0 to your computer and use it in GitHub Desktop.
uploading files to S3 in shell with a little bit of curl and openssl
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
# https://gist.github.com/ansemjo/cc113ced5d133c018e95079ddb003bb0 | |
set -e -o pipefail | |
usage() { cat >&2 <<USAGE | |
usage: s3put [-a acl] [-p pinnedkey] [-h] endpoint file objectpath | |
-a acl : use a different acl for uploaded files | |
-p pinnedkey : sha256 pinned public key for certificate validation | |
-h : display this help | |
endpoint : endpoint url, e.g. https://s3.exmaple.com:9000 | |
file : path to local file | |
objectpath : path to remote file | |
USAGE | |
} | |
err() { echo "err: $1" >&2; usage; } | |
# parse commandline options | |
while getopts ":a:p:h" OPT; do | |
case "$OPT" in | |
a) # use a different ACL | |
export ACL="$OPTARG" ;; | |
p) # pinned public key: | |
# curl "${1:?url required}" --ssl --pinnedpubkey sha256//invalid -kv 2>&1 | sed -n 's/.*public key hash: //p' | |
export PINNEDPUBKEY="$OPTARG" ;; | |
h) # display help | |
usage; exit 0 ;; | |
\?) # unknown option | |
err "invalid option: $OPT"; exit 1 ;; | |
:) # missing argument | |
err "invalid option: $OPT requires an argument"; exit 1 ;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
# remaining required arguments | |
ENDPOINT=$1 | |
FILE=$2 | |
OBJECTPATH=$3 | |
if [[ ! $ENDPOINT ]] || [[ ! $FILE ]] || [[ ! $OBJECTPATH ]]; then | |
err "three arguments required" | |
exit 1 | |
fi | |
# ACCESS_KEY and SECRET_KEY are required in environment | |
if [[ ! ${ACCESS_KEY+defined} ]] || [[ ! ${SECRET_KEY+defined} ]]; then | |
err "ACCESS_KEY and SECRET_KEY are required in env" | |
exit 1 | |
fi | |
# prepare for object upload | |
# see: https://gist.github.com/chrismdp/6c6b6c825b07f680e710 | |
ACL="${ACL:-x-amz-acl:public-read}" | |
CONTENTTYPE="application/octet-stream" | |
DATE="$(LC_ALL=en_US.utf8 date --utc +'%a, %d %b %Y %T %z')" | |
STRING="PUT\n\n$CONTENTTYPE\n$DATE\n$ACL\n/$OBJECTPATH" | |
SIGNATURE="$(echo -ne "$STRING" | openssl dgst -sha1 -hmac "$SECRET_KEY" -binary | openssl base64)" | |
# upload with curl | |
curl -f -X PUT -T "$FILE" \ | |
-H "Host: $(basename "$ENDPOINT")" \ | |
-H "Date: $DATE" \ | |
-H "Content-Type: $CONTENTTYPE" \ | |
-H "$ACL" \ | |
-H "Authorization: AWS $ACCESS_KEY:$SIGNATURE" \ | |
$([[ ${PINNEDPUBKEY+defined} ]] && echo -k --pinnedpubkey "$PINNEDPUBKEY") \ | |
"$ENDPOINT/$OBJECTPATH" >/dev/null |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment