mirror of
https://github.com/9001/copyparty.git
synced 2025-08-16 08:32:13 -06:00
225 lines
4.3 KiB
Bash
225 lines
4.3 KiB
Bash
#!/bin/bash
|
|
set -e
|
|
|
|
# upload $datalen worth of generated data with a random filename,
|
|
# using a single connection for all chunks
|
|
|
|
|
|
##
|
|
## config
|
|
|
|
datalen=$((128*1024*1024))
|
|
target=127.0.0.1
|
|
posturl=/inc
|
|
passwd=wark
|
|
|
|
|
|
##
|
|
## derived/generated
|
|
|
|
salt=$(head -c 21 /dev/urandom | base64 -w0 | tr '+/' '-_')
|
|
datalen=$((datalen-3))
|
|
|
|
openssl enc -aes-256-ctr -pass pass:$salt -nosalt < /dev/zero 2>/dev/null |
|
|
head -c 524287 > /dev/shm/$salt.bin #2147483647
|
|
|
|
|
|
##
|
|
## functions
|
|
|
|
# produce a stream of data
|
|
gendata() {
|
|
while true; do
|
|
cat /dev/shm/$salt.bin{,,,,,,,,,,,,,,,,,,}
|
|
done
|
|
}
|
|
|
|
# pipe a chunk, get the base64 checksum
|
|
gethash() {
|
|
printf $(
|
|
sha512sum | cut -c-66 |
|
|
sed -r 's/ .*//;s/(..)/\\x\1/g'
|
|
) |
|
|
base64 -w0 | cut -c-44 |
|
|
tr '+/' '-_'
|
|
}
|
|
|
|
# division except ceil() instead of floor()
|
|
ceildiv() {
|
|
local num=$1
|
|
local div=$2
|
|
echo $(((num+div-1)/div))
|
|
}
|
|
|
|
# provide filesize, get correct chunksize
|
|
getchunksize() {
|
|
local filesize=$1
|
|
local chunksize=$((1024 * 1024))
|
|
local stepsize=$((512 * 1024))
|
|
while true; do
|
|
for mul in 1 2; do
|
|
local nchunks=$(ceildiv filesize chunksize)
|
|
|
|
[ $nchunks -le 256 ] ||
|
|
[ $chunksize -ge $((32 * 1024 * 1024)) ] && {
|
|
echo $chunksize
|
|
return
|
|
}
|
|
|
|
chunksize=$((chunksize+stepsize))
|
|
stepsize=$((stepsize*mul))
|
|
done
|
|
done
|
|
}
|
|
|
|
# pipe data + provide full length, get all chunk checksums
|
|
gethashes() {
|
|
local datalen=$1
|
|
local chunksize=$(getchunksize $datalen)
|
|
local nchunks=$(ceildiv $datalen $chunksize)
|
|
|
|
echo >&2
|
|
while [ $nchunks -gt 0 ]
|
|
do
|
|
head -c $chunksize | gethash
|
|
nchunks=$((nchunks-1))
|
|
printf '\033[Ahash %s \n' $nchunks >&2
|
|
done
|
|
}
|
|
|
|
# pipe handshake response, get wark
|
|
getwark() {
|
|
awk '/"wark": ?"/ {sub(/.*"wark": ?"/,"");sub(/".*/,"");print}'
|
|
}
|
|
|
|
|
|
##
|
|
## create handshake json
|
|
|
|
chunksize=$(getchunksize $datalen)
|
|
|
|
printf '{"name":"%s.bin","size":%d,"hash":[' $salt $datalen >/dev/shm/$salt.hs
|
|
|
|
printf '\033[33m'
|
|
gendata |
|
|
head -c $datalen |
|
|
gethashes $datalen > /dev/shm/$salt.hl
|
|
printf '\033[0m'
|
|
|
|
IFS=$'\n' GLOBIGNORE='*' command eval 'HASHES=($(cat "/dev/shm/$salt.hl"))'
|
|
|
|
awk '{printf "%s\"%s\"", v, $0; v=","}' /dev/shm/$salt.hl >> /dev/shm/$salt.hs
|
|
|
|
printf ']}' >> /dev/shm/$salt.hs
|
|
|
|
|
|
##
|
|
## post handshake
|
|
|
|
printf '\033[36m'
|
|
|
|
#curl "http://$target:3923$posturl/handshake.php" -H "Content-Type: text/plain;charset=UTF-8" -H "Cookie: cppwd=$passwd" --data "$(cat "/dev/shm/$salt.hs")" | tee /dev/shm/$salt.res
|
|
|
|
{
|
|
{
|
|
cat <<EOF
|
|
POST $posturl/ HTTP/1.1
|
|
Connection: Close
|
|
Cookie: cppwd=$passwd
|
|
Content-Type: text/plain;charset=UTF-8
|
|
Content-Length: $(cat /dev/shm/$salt.hs | wc -c)
|
|
|
|
EOF
|
|
} | sed -r 's/$/\r/'
|
|
|
|
cat /dev/shm/$salt.hs
|
|
} |
|
|
tee /dev/shm/$salt.hsb |
|
|
ncat $target 3923 |
|
|
tee /dev/shm/$salt.hs1r
|
|
|
|
wark="$(cat /dev/shm/$salt.hs1r | getwark)"
|
|
printf '\033[0m\nwark: %s\n' $wark
|
|
|
|
|
|
##
|
|
## wait for signal to continue
|
|
|
|
true || {
|
|
w8=/dev/shm/$salt.w8
|
|
touch $w8
|
|
|
|
echo "ready; rm -f $w8"
|
|
|
|
while [ -e $w8 ]; do
|
|
sleep 0.2
|
|
done
|
|
}
|
|
|
|
|
|
##
|
|
## post chunks
|
|
|
|
t0=$(date +%s.%N)
|
|
remains=$datalen
|
|
nchunk=0
|
|
|
|
gendata |
|
|
head -c $datalen |
|
|
while [ $remains -gt 0 ]; do
|
|
[ $remains -ge $chunksize ] &&
|
|
postlen=$chunksize ||
|
|
postlen=$remains
|
|
|
|
printf '\n\n=> %s %s\n' $remains $postlen >&2
|
|
|
|
remains=$((remains-postlen))
|
|
|
|
{
|
|
cat <<EOF
|
|
POST $posturl/ HTTP/1.1
|
|
Connection: Keep-Alive
|
|
Cookie: cppwd=$passwd
|
|
Content-Type: application/octet-stream
|
|
Content-Length: $postlen
|
|
X-Up2k-Hash: ${HASHES[$nchunk]}
|
|
X-Up2k-Wark: $wark
|
|
|
|
EOF
|
|
} | sed -r 's/$/\r/'
|
|
|
|
head -c $postlen
|
|
nchunk=$((nchunk+1))
|
|
|
|
done |
|
|
ncat $target 3923 |
|
|
tee /dev/shm/$salt.pr
|
|
|
|
t=$(date +%s.%N)
|
|
|
|
|
|
##
|
|
## handshake again
|
|
|
|
printf '\033[36m'
|
|
|
|
ncat $target 3923 < /dev/shm/$salt.hsb |
|
|
tee /dev/shm/$salt.hs2r |
|
|
grep -E '"hash": ?\[ *\]'
|
|
|
|
rv=$?
|
|
|
|
[ $rv -eq 0 ] &&
|
|
printf '\033[32mok\033[0m\n' ||
|
|
printf '\033[31mERROR\033[0m\n'
|
|
|
|
td=$(echo "scale=3; $t-$t0" | bc)
|
|
spd=$(echo "scale=3; ($datalen/$td)/(1024.0*1024)" | bc)
|
|
|
|
printf '%.3f sec, %.3f MiB/s\n' $td $spd |
|
|
tee /dev/shm/$salt.spd
|
|
|
|
exit $rv
|
|
|
|
# find /dev/shm/ -maxdepth 1 -type f | grep -E '/[a-zA-Z0-9_-]{28}\.[a-z0-9]+$' | xargs rm; for n in {1..8}; do ./up2k.sh & done; wait; cat /dev/shm/*.spd | sort -n
|