diff --git a/bashttpd b/bashttpd index 9ed8d21..b632070 100755 --- a/bashttpd +++ b/bashttpd @@ -6,10 +6,11 @@ # # Original author: Avleen Vig, 2012 # Reworked by: Josh Cartwright, 2012 +# QA: Jacob Hrbek, 2019 -warn() { echo "WARNING: $@" >&2; } +warn() { printf 'WARNING %s\n' "$@" >&2; } -[ -r bashttpd.conf ] || { +[ ! -e bashttpd.conf ] && { cat >bashttpd.conf <<'EOF' # # bashttpd.conf - configuration for bashttpd @@ -104,13 +105,15 @@ EOF exit 1 } -recv() { echo "< $@" >&2; } -send() { echo "> $@" >&2; - printf '%s\r\n' "$*"; } +recv() { printf "< %s\n" "$@" >&2; } +send() { + printf "> %s\n" "$@" >&2 + printf '%s\r\n' "$*" +} -[[ $UID = 0 ]] && warn "It is not recommended to run bashttpd as root." +[ -z "$(id -u)" ] && warn "It is not recommended to run bashttpd as root." -DATE=$(date +"%a, %d %b %Y %H:%M:%S %Z") +DATE="$(date +"%a, %d %b %Y %H:%M:%S %Z")" declare -a RESPONSE_HEADERS=( "Date: $DATE" "Expires: $DATE" @@ -131,7 +134,7 @@ declare -a HTTP_RESPONSE=( ) send_response() { - local code=$1 + local code="$1" send "HTTP/1.0 $1 ${HTTP_RESPONSE[$1]}" for i in "${RESPONSE_HEADERS[@]}"; do send "$i" @@ -150,9 +153,9 @@ fail_with() { } serve_file() { - local file=$1 + local file="$1" - CONTENT_TYPE= + CONTENT_TYPE="" case "$file" in *\.css) CONTENT_TYPE="text/css" @@ -180,7 +183,7 @@ serve_dir_with_tree() add_response_header "Content-Type" "text/html" # The --du option was added in 1.6.0. - read x tree_vers x < <(tree --version) + read -r x tree_vers x < <(tree --version) [[ $tree_vers == v1.6* ]] && tree_opts="--du" send_response_ok_exit < \ @@ -189,7 +192,7 @@ serve_dir_with_tree() serve_dir_with_ls() { - local dir=$1 + local dir="$1" add_response_header "Content-Type" "text/plain" @@ -198,7 +201,7 @@ serve_dir_with_ls() } serve_dir() { - local dir=$1 + local dir="$1" # If `tree` is installed, use that for pretty output. which tree &>/dev/null && \ @@ -210,22 +213,22 @@ serve_dir() { } serve_dir_or_file_from() { - local URL_PATH=$1/$3 + local URL_PATH="$1/$3" shift # sanitize URL_PATH - URL_PATH=${URL_PATH//[^a-zA-Z0-9_~\-\.\/]/} - [[ $URL_PATH == *..* ]] && fail_with 400 + URL_PATH="${URL_PATH//[^a-zA-Z0-9_~\-\.\/]/}" + [[ "$URL_PATH" == *..* ]] && fail_with 400 # Serve index file if exists in requested directory - [[ -d $URL_PATH && -f $URL_PATH/index.html && -r $URL_PATH/index.html ]] && \ + [ -d "$URL_PATH" ] && [ -f "$URL_PATH/index.html" ] && [ -r "$URL_PATH/index.html" ] && \ URL_PATH="$URL_PATH/index.html" - if [[ -f $URL_PATH ]]; then - [[ -r $URL_PATH ]] && \ + if [ -f "$URL_PATH" ]; then + [ -r "$URL_PATH" ] && \ serve_file "$URL_PATH" "$@" || fail_with 403 - elif [[ -d $URL_PATH ]]; then - [[ -x $URL_PATH ]] && \ + elif [ -d "$URL_PATH" ]; then + [ -x "$URL_PATH" ] && \ serve_dir "$URL_PATH" "$@" || fail_with 403 fi @@ -238,10 +241,10 @@ serve_static_string() { } on_uri_match() { - local regex=$1 + local regex="$1" shift - [[ $REQUEST_URI =~ $regex ]] && \ + [[ "$REQUEST_URI" =~ $regex ]] && \ "$@" "${BASH_REMATCH[@]}" } @@ -253,7 +256,7 @@ unconditionally() { read -r line || fail_with 400 # strip trailing CR if it exists -line=${line%%$'\r'} +line="${line%%$'\r'}" recv "$line" read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<<"$line" @@ -269,7 +272,7 @@ read -r REQUEST_METHOD REQUEST_URI REQUEST_HTTP_VERSION <<<"$line" declare -a REQUEST_HEADERS while read -r line; do - line=${line%%$'\r'} + line="${line%%$'\r'}" recv "$line" # If we've reached the end of the headers, break.