1
0
Fork 0
mirror of https://github.com/notwa/rc synced 2024-09-19 09:14:05 -07:00
rc/sh/burl

77 lines
2.6 KiB
Bash
Executable file

#!/usr/bin/env bash
# compat: +ash +bash +dash -hush +ksh +mksh +oksh +osh +posh +yash +zsh
burl() ( ### @-
### turn bash into a makeshift HTTP client.
### inspired by [hackshell.sh.](https://thc.org/hs)
### also works in most other shells thanks to netcat.
###
### minimal/minified version: https://eaguru.guru/t/burl.sh (469 bytes)
###
### ```
### $ burl httpbin.org/get
###
### HTTP/1.1 200 OK
### Date: Tue, 01 Jul 2024 00:00:00 GMT
### Content-Type: application/json
### Content-Length: 192
### Connection: close
### Server: gunicorn/19.9.0
### Access-Control-Allow-Origin: *
### Access-Control-Allow-Credentials: true
###
### {
### "args": {},
### "headers": {
### "Host": "httpbin.org",
### "X-Amzn-Trace-Id": "Root=1-12345678-deadfadefeedfacebeefcafe"
### },
### "origin": "0.0.0.0",
### "url": "http://httpbin.org/get"
### }
### ```
# shells with /dev/tcp and /dev/udp support: bash, ksh, yash.
! (set -o pipefail) 2>&- || set -o pipefail
(: </dev/udp/localhost/0) 2>&- && net=y || net=
[ $'' ] && r=$(printf \\r) || r=$'\r'
# nc.traditional needs the -- or else it waits for input.
if /usr/bin/env nc --; [ $? = 1 ] # needs absolute path to env thanks to busybox
then wrapped() { process /usr/bin/env nc -- "$@" ;}
elif netcat; [ $? = 1 ]
then wrapped() { process netcat -- "$@" ;}
elif ncat; [ $? = 1 ]
then wrapped() { process ncat -- "$@" ;}
elif busybox nc; [ $? = 1 ]
then wrapped() { process busybox nc -- "$@" ;}
elif socat /dev/null /dev/null
then wrapped() { process socat - "TCP:$1:$2" ;}
elif websocat; [ $? = 1 ]
then wrapped() { websocat --binary - "tcp:$1:$2" ;}
elif curl; [ $? = 2 ]
then wrapped() { process curl "telnet://$1:$2" ;}
else return 127
fi 2>&-
request() { printf 'GET /%s HTTP/1.0\r\nHost: %s\r\n\r\n' "${query#/}" "$dom" ;}
receive() { while IFS=$r read -r l _; [ "$l" ]; do printf %s\\n "$l"; done; echo ;} >&2
process() { request | "$@" | { receive && cat ;} ;}
for url; do
proto="${url%%:*}" proto="${proto##*[!a-z0-9-]*}"
[ "$proto" ] && url="${url#$proto://}" || url="${url#//}"
host="${url%%/*}" query="${url#"$host"}" dom="${host%:*}"
[ "$host" = "${dom:?}" ] && PORT="${PORT:-80}" || PORT="${host##*:}"
if [ "$net" ]; then
exec 3<>"/dev/tcp/$dom/$PORT" &&
request >&3 && receive <&3 && cat <&3 || continue
exec 3>&-
else
wrapped "$dom" "$PORT" || return
fi
done
)
[ -n "${preload+-}" ] || burl "$@"