Skip to content

Instantly share code, notes, and snippets.

@dannysauer
Last active January 29, 2022 03:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dannysauer/1299a9c95ad58a235a74bec4bab8484c to your computer and use it in GitHub Desktop.
Save dannysauer/1299a9c95ad58a235a74bec4bab8484c to your computer and use it in GitHub Desktop.
Stupid shell tricks

One-liner to accept incoming http POST data and then relay it to some number of POST endpoints.

while true; do printf 'HTTP/1.0 200 OK\r\nContent-Length: 0\r\n' | { nc -q1 -l 8080; echo; } | sed '0,/^[[:space:]]*$/d' | tee >(http POST http://localhost:8081/path1) >(http POST http://localhost:8081/path2); done

With some linebreaks so it's readable:

while true
do
  printf 'HTTP/1.0 200 OK\r\nContent-Length: 0\r\n' \
  | { nc -q1 -l 8080; echo; } \
  | sed '0,/^[[:space:]]*$/d' \
  | tee \
    >(http POST http://localhost:8081/path1) \
    >(http POST http://localhost:8081/path2)
done
  • Data being resubmitted is logged to STDOUT along with the response from the relay targets
  • I just used another netcat instance as the web server, because lazy; who knows how this works with real problems
  • This uses httpie because web developers have convinced me that's the right way to do things
  • There is basically no error checking at all, so there's a strong chance this will explode your house, computers, and things that actually need it to run
#!/bin/bash
DELAY=5
function kid {
local count=0
# wait roughly half the time between polling loops because nyquist
# "roughly" because bash doesn't do floating point :/
local webdelay=$(( ( DELAY / 2 ) ))
# just exit if the nc dies
# note that this only works if everything else here is a builtin
trap "exit" CHLD INT
coproc nc -lk 8080
echo "child spawned $COPROC_PID" >&2
while true
do
echo "loop" >&2
# wait a quarter second for new data; should be more than enough
read -t 0.25
if [[ $REPLY == +([0-9]) ]]
then
: $(( count += REPLY ))
echo "count is now $count" >&2
fi
# check for a web client.
read -t $webdelay -u ${COPROC[0]}
if [[ -n $REPLY ]]
then
{
if [[ $REPLY == @(GET /metrics*(/)*) ]]
then
msg="count is $count"
printf "HTTP/1.1 200 OK\r\n"
else
msg="unsupported"
printf "HTTP/1.1 400 not metrics\r\n"
fi
printf "Content-Type: text/plain\r\n"
printf "Content-Length: ${#msg}\r\n"
printf "\r\n"
printf "$msg"
} >&${COPROC[1]}
while read -t $webdelay -u ${COPROC[0]}
do
[[ -z $REPLY ]] && break
done
echo "I served a client!" >&2
fi
done
}
coproc kid
trap "kill $COPROC_PID && exit" EXIT INT
echo "Process $$ spawned $COPROC_PID"
while sleep $DELAY
do
printf "3\n" >&${COPROC[1]}
done
echo "and now we're done"
@dannysauer
Copy link
Author

The "sketchy web server" doesn't like getting hit many times in a row. This is fine, because it's a terrible idea to write a web server this way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment