Compare commits

..

5 Commits

Author SHA1 Message Date
edccec4ad0 one more debug line 2026-05-03 00:20:28 +03:00
af70e91d0e CRLF the protocol, as per the RFC 2026-05-03 00:20:14 +03:00
7d051690f5 support urlencoded names 2026-05-03 00:19:50 +03:00
e6f049da4b fix SECURITY bug with local address not being used 2026-05-03 00:19:19 +03:00
866ecc9302 remove unused function 2026-05-03 00:03:35 +03:00

View File

@ -6,30 +6,23 @@ ADDR=127.0.0.1
PORT=1234 PORT=1234
ROOT="$(realpath "${1:-$PWD}")" ROOT="$(realpath "${1:-$PWD}")"
CR=$'\r'
LF=$'\n' LF=$'\n'
tmpdir="$(mktemp -d)" tmpdir="$(mktemp -d)"
trap 'rm -r "$tmpdir"' EXIT trap 'rm -r "$tmpdir"' EXIT
trap 'exit' INT trap 'exit' INT
stdhead() {
code="$1"
head="$2"
echo "HTTP/1.0 $code $head"
echo "Content-Type: text/plain"
echo "Connection: close"
}
error() { error() {
code="$1" code="$1"
head="$2" head="$2"
message="$3" message="$3"
echo "HTTP/1.0 $code $head" echo "HTTP/1.0 $code $head$CR"
echo "Content-Type: text/plain" echo "Content-Type: text/plain$CR"
echo "Connection: close" echo "Connection: close$CR"
echo echo "$CR"
echo "$code $head" echo "$code $head$CR"
echo echo "$CR"
echo "$message" echo "$message"
exit exit
} }
@ -39,7 +32,7 @@ handle() {
response_pipe="$tmpdir/response-$connection_id.pipe" response_pipe="$tmpdir/response-$connection_id.pipe"
event_pipe="$tmpdir/event-$connection_id.pipe" event_pipe="$tmpdir/event-$connection_id.pipe"
mkfifo -m 0600 "$response_pipe" "$event_pipe" mkfifo -m 0600 "$response_pipe" "$event_pipe"
gnetcat -c -l "$ADDR" -p "$PORT" < "$response_pipe" | sed -E -u 's/\r$//' | ( gnetcat --listen --source "$ADDR" --local-port "$PORT" --close < "$response_pipe" | sed -E -u 's/\r$//' | (
read method url version || { read method url version || {
echo "Connection broken" > "$event_pipe" echo "Connection broken" > "$event_pipe"
exit exit
@ -52,6 +45,7 @@ handle() {
if ! [ "$method" = "GET" ]; then if ! [ "$method" = "GET" ]; then
error 501 'Not Implemented' "Method $method is not implemented.${LF}Only GET is supported." error 501 'Not Implemented' "Method $method is not implemented.${LF}Only GET is supported."
fi fi
url="$(echo "$url" | urlencode -d)"
if ! echo "$url" | grep -q '^/'; then if ! echo "$url" | grep -q '^/'; then
error 400 'Bad Request' "URL must be host-relative" error 400 'Bad Request' "URL must be host-relative"
fi fi
@ -61,24 +55,24 @@ handle() {
target="$ROOT$url" target="$ROOT$url"
name=$(basename "$url") name=$(basename "$url")
if [ -f "$target" ]; then if [ -f "$target" ]; then
echo "HTTP/1.0 200 OK" echo "HTTP/1.0 200 OK$CR"
echo "Connection: close" echo "Connection: close$CR"
echo echo "$CR"
cat "$target" cat "$target"
exit exit
fi fi
if [ -d "$target" ]; then if [ -d "$target" ]; then
if ! echo "$url" | grep -q '/$'; then if ! echo "$url" | grep -q '/$'; then
echo "HTTP/1.0 307 Temporary Redirect" echo "HTTP/1.0 307 Temporary Redirect$CR"
echo "Connection: close" echo "Connection: close$CR"
echo "Location: $url/" echo "Location: $url/$CR"
exit exit
fi fi
ls "$target" 2>/dev/null | { ls "$target" 2>/dev/null | {
echo "HTTP/1.0 200 OK" echo "HTTP/1.0 200 OK$CR"
echo "Content-Type: text/html; charset=utf-8" echo "Content-Type: text/html; charset=utf-8$CR"
echo "Connection: close" echo "Connection: close$CR"
echo echo "$CR"
echo "<!DOCTYPE html>" echo "<!DOCTYPE html>"
echo "<title>Directory listing for $url</title>" echo "<title>Directory listing for $url</title>"
echo "<h1>$name</h1>" echo "<h1>$name</h1>"
@ -105,6 +99,7 @@ handle() {
rm "$event_pipe" rm "$event_pipe"
} }
echo "Listening at $ADDR:$PORT"
echo "Serving $ROOT" echo "Serving $ROOT"
for((i=0;;i++)); do for((i=0;;i++)); do