Last active
May 5, 2019 15:08
-
-
Save mwgamera/52108d05cdc2161843c036482828650b to your computer and use it in GitHub Desktop.
Product of some lunacy; usable for foot-shooting, maybe.
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
#!/bin/sh | |
# klg, Dec 2018 | |
set -e | |
if ! [ '/--slave' = "/$1" ] | |
then | |
root_dir="${1:-.}"; ( cd "$root_dir"; ) | |
charset=$(locale charmap 2>/dev/null || :) | |
echo >&2 "Serving $root_dir on http://localhost:${PORT:=8000}/ ..." | |
exec env - "PATH=$PATH" "charset=$charset" "root_dir=$root_dir" \ | |
socat "TCP6-LISTEN:$PORT,reuseaddr,fork" "EXEC:$0 --slave" | |
fi | |
export LC_ALL=C | |
cd "$root_dir" | |
: "${charset:=L1}" | |
htmlesc() { | |
echo "$@" | sed \ | |
-e 's/\&/\&/g' \ | |
-e 's/</\</g' \ | |
-e 's/>/\>/g' \ | |
-e 's/"/\"/g' \ | |
-e 's/'\''/\'/g' | |
} | |
mime_ext() { | |
set -- "${1##*.}" | |
case "$1" in | |
([Hh][Tt][Mm]|[Hh][Tt][Mm][Ll]) echo 'text/html' ;; | |
([Tt][Xx][Tt]) echo 'text/plain' ;; | |
(*) awk -v "ext=$1" 'BEGIN{ext=tolower(ext)} | |
!/^#/&&$2{for(i=2;i<=NF;i++)if(ext==tolower($i)){print$1;exit}}' /etc/mime.types ;; | |
esac | |
} | |
error() { | |
code="$1"; shift | |
case "$code" in | |
(301) status='Moved Permanently';; | |
(302) status='Moved Temporarily';; | |
(403) status='Forbidden';; | |
(404) status='Not Found';; | |
(405) status='Method Not Allowed'; set -- "$@" 'Allow:GET';; | |
(*) status=Error;; | |
esac | |
if [ -n "$SERVER_PROTOCOL" ] | |
then | |
printf '%s\r\n' "HTTP/1.0 $code $status" \ | |
"Content-Type:text/html;charset=$charset" "$@" '' | |
fi | |
code=$(htmlesc "$code") | |
status=$(htmlesc "$status") | |
echo "<!doctype html><html lang=\"en\"><meta charset=\"$charset\">" | |
echo "<title>$code - $status</title><h1>$code — $status</h1>" | |
exit | |
} | |
send_file() { | |
[ -r "$REQUEST_FILE" ] || error 403 | |
if [ -n "$SERVER_PROTOCOL" ] | |
then | |
set -- | |
mime_type=$(attr -q -g mime_type "$REQUEST_FILE" 2>/dev/null || :) | |
charset=$(attr -q -g charset "$REQUEST_FILE" 2>/dev/null || :) | |
: "${mime_type:=$(mime_ext "$REQUEST_FILE")}" | |
set -- "$@" "Content-Type:${mime_type:-text/plain}${charset:+";charset=$charset"}" | |
printf '%s\r\n' 'HTTP/1.0 200 OK' "$@" '' | |
fi | |
exec cat "$REQUEST_FILE" | |
} | |
dir_listing() { | |
[ -r "$REQUEST_FILE" ] || error 403 | |
if [ -n "$SERVER_PROTOCOL" ] | |
then | |
set -- "Content-Type:text/html;charset=$charset" | |
printf '%s\r\n' 'HTTP/1.0 200 OK' "$@" '' | |
fi | |
echo "<!doctype html><html lang=\"en\"><meta charset=\"$charset\">" | |
html_dir="$(htmlesc "${REQUEST_URI%/}")" | |
echo "<title>Index of ${html_dir:-/}</title><h1>Index of ${html_dir:-/}</h1>" | |
echo '<ul>' | |
for file in "$REQUEST_FILE"/* | |
do | |
html_file=$(htmlesc "${file##*/}") | |
#html_path=$(printf '%s' "${file##*/}"| od -An -tx1 | tr -d '\n' | tr ' ' '%') | |
html_path="$html_file" # this ok if charset is utf8 | |
if [ -x "$file/" ] | |
then | |
echo "<li><a href=\"$html_dir/$html_path/\">$html_file/</a></li>" | |
elif [ -f "$file" ] | |
then | |
echo "<li><a href=\"$html_dir/$html_path\">$html_file</a></li>" | |
fi | |
done | |
echo '</ul>' | |
} | |
read -r REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL | |
echo >&2 "$SOCAT_PEERADDR \"$(echo "$REQUEST_METHOD $REQUEST_URI ${SERVER_PROTOCOL% }" | sed 's/[^ -~]/?/g')\"" | |
case "$REQUEST_METHOD" in ([Gg][Ee][Tt]);; (*) error 405;; esac | |
REQUEST_FILE=$(echo "./$REQUEST_URI" | sed -e "$(awk 'BEGIN { | |
for(i = 1; i < 256; i++) | |
if (i != 25) | |
if (i >= 48 && i <= 57 || i >= 65 && i < 128 && i != 92) | |
printf("s/%%%02X/%c/gi;", i, i); | |
else | |
printf("s/%%%02X/\\%c/gi;", i, i); | |
print("s/%25/%/gi"); | |
}')") | |
case "$REQUEST_FILE" in (*/.*) error 403;; esac | |
if [ -f "$REQUEST_FILE" ] | |
then | |
send_file | |
elif [ -d "$REQUEST_FILE/" ] | |
then | |
[ "/$REQUEST_FILE" = "/${REQUEST_FILE%/}" ] && error 301 "Location:$REQUEST_URI/" | |
if [ -f "$REQUEST_FILE/index.html" ] | |
then | |
REQUEST_FILE="$REQUEST_FILE/index.html" | |
send_file | |
else | |
dir_listing | |
fi | |
else | |
error 404 | |
fi |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment