ssh-treasure-hunt/http_bash.sh

112 lines
2.4 KiB
Bash
Raw Permalink Normal View History

2022-01-20 16:09:16 +00:00
#!/usr/bin/env bash
#
# A simple, configurable HTTP server written in bash.
#
# See LICENSE for licensing information.
#
# Original author: Avleen Vig, 2012
# Reworked by: Josh Cartwright, 2012
warn() { echo "WARNING: $@" >&2; }
recv() { echo "< $@" >&2; }
send() { echo "> $@" >&2;
printf '%s\r\n' "$*"; }
[[ $UID = 0 ]] && warn "It is not recommended to run bashttpd as root."
DATE=$(date +"%a, %d %b %Y %H:%M:%S %Z")
declare -a RESPONSE_HEADERS=(
"Date: $DATE"
"Expires: $DATE"
"Server: Slash Bin Slash Bash"
)
add_response_header() {
RESPONSE_HEADERS+=("$1: $2")
}
declare -a HTTP_RESPONSE=(
[200]="OK"
[400]="Bad Request"
[403]="Forbidden"
[404]="Not Found"
[405]="Method Not Allowed"
[500]="Internal Server Error"
)
send_response() {
local code=$1
send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}"
for i in "${RESPONSE_HEADERS[@]}"; do
send "$i"
done
send
while read -r line; do
send "$line"
done
}
send_response_ok_exit() { send_response 200; exit 0; }
fail_with() {
send_response "$1" <<< "$1 ${HTTP_RESPONSE[$1]}"
exit 1
}
serve_static_string() {
add_response_header "Content-Type" "text/plain;charset=utf-8"
send_response_ok_exit <<< "$1"
}
2022-01-20 18:45:04 +00:00
where () {
h="$(dirname "$0")"
# If $h isnt absolute, prepend working dir
if [[ ! "${h:0:1}" = "/" ]] ; then
h="$(pwd)/$(dirname "$0")"
fi
h="$(realpath "$h")"
echo "$h"
}
2022-01-20 16:09:16 +00:00
main () {
2022-01-20 18:45:04 +00:00
# Request uri must be a relative path from the exercices/corriges directory
2022-01-20 16:09:16 +00:00
[ -x "$REQUEST_URI" ] || [ ! -d "$REQUEST_URI" ] || fail_with 404
2022-01-20 18:45:04 +00:00
here="$(where)"
path="$(realpath "$here/exercices/corriges/$REQUEST_URI")"
[[ "$path" = "$here"* ]] || fail_with 404
serve_static_string "$(basename "$path" | cut -d '.' -f 1) : $(bash "$path" 2>&1 && echo Ok || echo 'Non validé')"
2022-01-20 16:09:16 +00:00
}
# Request-Line HTTP RFC 2616 $5.1
read -r line || fail_with 400
# strip trailing CR if it exists
line=${line%%$'\r'}
recv "$line"
read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<<"$line"
[ -n "$REQUEST_METHOD" ] && \
[ -n "$REQUEST_URI" ] && \
[ -n "$REQUEST_HTTP_VERSION" ] \
|| fail_with 400
# Only GET is supported at this time
[ "$REQUEST_METHOD" = "GET" ] || fail_with 405
declare -a REQUEST_HEADERS
while read -r line; do
line=${line%%$'\r'}
recv "$line"
# If we've reached the end of the headers, break.
[ -z "$line" ] && break
REQUEST_HEADERS+=("$line")
done
main
fail_with 500