toymaker.git

commit fb7a6f8f294573fa25eeaabf34af9d9394623204

Author: Adam <git@apiote.xyz>

rename server

  | 0 


diff --git a/server2.sh b/server2.sh
deleted file mode 100755
index ad646f5371ce9db4eac1b6f5fdafc1ea7de562ef..0000000000000000000000000000000000000000
--- a/server2.sh
+++ /dev/null
@@ -1,391 +0,0 @@
-#!/bin/sh
-#
-# Based on server by Upper Stream (c) 2017, MIT license
-# (https://gist.github.com/upperstream/b9b77429bc024541b7605aea76086ad8)
-
-. start.sh
-. get.sh
-. password.sh
-
-set -e
-
-exec >>~/toymaker.log
-exec 2>&1
-
-# program name
-program=${0##*/}
-
-usage() {
-	cat <<-EOF
-	Usage:
-
-	$program [-p port] [docroot]
-	$program -h
-
-	-p port : specify listening port number; defaults to 1313
-	-h      : print this help and quit
-	docroot : specify document root directory; defaults to the current directory
-EOF
-}
-
-# default listening port
-port=1313
-
-# Configure in accordance with your environment
-nc=$(command -v nc) || true
-
-# todo mktmp
-pid_file=/tmp/$program.pid
-
-slashes() {
-	printf "%s" "$1" | sed 's|[^/]||g' | wc -m
-}
-
-field() {
-	echo "$1" | cut -d '/' -f "$2"
-}
-makefifo() {
-	name="$1"
-	mkfifo -m 0600 "/tmp/$name.fifo" && echo "/tmp/$name.fifo"
-}
-
-templateMessage() {
-	message=$1
-	templateName=$2
-	contentType=$3
-	case $contentType in
-		text/plain)
-			ext='txt'
-			;;
-		text/html|\*|\*/\*|'')
-			ext='html'
-			;;
-		image/\*|image/svg)
-			ext='svg'
-			;;
-		*)
-		return 1
-		;;
-	esac
-	[ -f "templates/$templateName.$ext" ] || return 1
-	#shellcheck disable=SC1090
-	. "templates/$templateName.$ext"
-	template "$message"
-}
-
-respond200() {
-	page="$1"
-	contentType="$2"
-	[ -z "$contentType" ] && contentType='text/html'
-
-	# { cat "$fifo2" > /dev/null; printf ""; } > "$fifo1" &
-
-	printf "HTTP/1.1 200 OK\r\nContent-Length: %s\r\nContent-Type: %s\r\n\r\n%s\r\n" "${#page}" "$contentType" "$page" > "$fifo1"
-
-	# printf "%s\r\n" "$page" >> "$fifo1"
-
-	# sleep 1; echo "end" > "$fifo2"
-	printf "200 %s" "${#page}"
-}
-
-respond200file() {
-	filePath="$1"
-	contentType="$2"
-
-	{ cat "$fifo2" > /dev/null; printf ""; } > "$fifo1" &
-
-	printf "HTTP/1.1 200 OK\r\nContent-Length: %s\r\nContent-Type: %s\r\n\r\n" "${#page}" "$contentType" >> "$fifo1"
-
-	cat "$filePath" >> "$fifo1"
-
-	sleep 1; echo "end" > "$fifo2"
-	printf "200 %s" "${#page}"
-}
-
-respond202() {
-	toy=$1
-	item=$2
-	message=$3
-	contentType="$4"
-	[ -z "$contentType" ] && contentType='text/html'
-	printf "HTTP/1.1 202 Accepted\r\nContent-Length: %s\r\nLocation: /toys/%s/%s\r\n\r\n%s\r\n" "${#message}" "$toy" "$item" "$message" > "$fifo1"
-	printf "202 -"
-}
-
-respond401() {
-	message=""
-	printf "HTTP/1.1 401 Unauthorized\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "401 -"
-}
-
-respond403() {
-	message=""
-	printf "HTTP/1.1 403 Forbidden\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "403 -"
-}
-
-respond404() {
-	path=$1
-	# todo html
-	message="$path not found"
-	printf "HTTP/1.1 404 Not Found\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "404 -"
-}
-
-respond405() {
-	method=$1
-	# todo html
-	message="$method unsupported"
-	printf "HTTP/1.1 405 Method Not Allowed\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "405 -"
-}
-
-respond406() {
-	contentType=$1
-	# todo html
-	message="$contentType unsupported"
-	printf "HTTP/1.1 406 Not Acceptable\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "406 -"
-}
-
-respond500() {
-	# todo html
-	message="Server error: $1"
-	printf "HTTP/1.1 500 Internal Server Error\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
-	printf "500 -"
-}
-
-check_auth() {
-	authorization=$1
-	stored=$(cat password)
-	if [ -z "$stored" ] || [ -z "$authorization" ]
-	then
-		respond401
-		return 1
-	fi
-	if ! printf '%s' "$authorization" | verify "$stored"
-	then
-		respond403
-		return 1
-	fi
-}
-
-execute() {
-	method="$1"
-	path="$2"
-	authorization="$3"
-	accept="$4"
-	_toys=$(field "$path" 2)
-	if [ "$_toys" != 'toys' ]
-	then
-		respond404 "$path"
-		return 1
-	fi
-
-	case $method in
-	GET)
-		if [ "$(slashes "$path")" -eq 2 ]
-		then
-			toy=$(field "$path" 3)
-			if [ "$toy"  = '' ]
-			then
-				if page=$(templateMessage "$(list_toys)" 'toys' 'text/html')
-				then
-					respond200 "$page"
-				else
-					respond406 "$accept"
-				fi
-			else
-				r=$(list_items "$toy")
-				status=$(echo "$r" | cut -d ';' -f 1)
-				if [ "$status" = 'n' ]
-				then
-					respond404 "$path"
-				elif page=$(templateMessage "$r" 'items' 'text/html')
-				then
-					respond200 "$page"
-				else
-					respond406 "$accept"
-				fi
-			fi
-		elif [ "$(slashes "$path")" -eq 3 ]
-		then
-			toy=$(field "$path" 3)
-			item=$(field "$path" 4)
-			if [ -z "$item" ]
-			then
-				respond404 "$path"
-				return 1
-			fi
-			r=$(show_item "$toy" "$item")
-			status=$(echo "$r" | cut -d ';' -f 1)
-			if [ "$status" = 'n' ]
-			then
-				respond404 "$path"
-			elif page=$(templateMessage "$r" 'item' "$accept")
-			then
-				if [ "$status" = 'r' ]
-				then
-					respond202 "$toy" "$item" "$page" "$accept"
-				else
-					respond200 "$page" "$accept"
-				fi
-			else
-				respond406 "$accept"
-			fi
-		elif [ "$(slashes "$path")" -eq 4 ]
-		then
-			toy=$(field "$path" 3)
-			item=$(field "$path" 4)
-			artifactName=$(field "$path" 5)
-			r=$(get_artifact "$toy" "$item" "$artifactName")
-			status=$(echo "$r" | cut -d ';' -f 1)
-			if [ "$status" = 'n' ]
-			then
-				respond404 "$path"
-			else
-				contentType=$(echo "$r" | cut -d ';' -f 2)
-				filePath=$(echo "$r" | cut -d ';' -f 3)
-				respond200file "$filePath" "$contentType"
-			fi
-		else
-			respond404 "$path"
-		fi
-		;;
-	POST)
-		check_auth "$authorization" || return
-
-		toy=$(field "$path" 3)
-		if [ "$(slashes "$path")" -ne 3 ] || [ -n "$(field "$path" 4)" ]
-		then
-			respond404 "$path"
-		fi
-
-		item=$(start_item "$toy")
-		if [ $! -gt 0 ]
-		then
-			respond500 "error while creating $toy"
-		else
-			respond202 "$toy" "$item"
-		fi
-
-		# todo delete old items, leave 1 stable, 1 errored
-		;;
-	DELETE)
-		check_auth "$authorization" || return
-
-		if [ "$(slashes "$path")" -eq 3 ]
-		then
-			toy=$(field "$path" 3)
-			item=$(field "$path" 4)
-			if stop_item "$toy" "$item"
-			then
-				respond200 ""
-			else
-				respond500 "error while stopping $toy/$item"
-			fi
-		else
-			respond404 "$path"
-		fi
-		;;
-	*)
-		respond405 "$method"
-		;;
-	esac
-}
-
-cleanup() {
-	rm "$fifo1" "$fifo2" "$pid_file"
-}
-
-interrupt() {
-	cleanup
-	exit 0
-}
-
-parse() {
-	cr=$(printf "\r")
-	while read -r line; do
-		line="${line%"$cr"}"
-		case "$line" in
-		GET*|POST*|PUT*|DELETE*|HEAD*|OPTIONS*|TRACE*)
-			# shellcheck disable=SC2086
-			set -- $line
-			method=$1
-			path=$2
-			;;
-		Host:*)
-			host=${line#Host: }
-			;;
-		Accept:*)
-			accept=${line#Accept: }
-			;;
-		Authorization:*)
-			authorization=${line#Authorization: }
-			;;
-		*:*)
-			;;
-		"")
-			date=$(date +'%d/%m/%Y:%H:%M:%S %z')
-			status_length=$(execute "$method" "$path" "$authorization" "$accept")
-			printf "%s %s \"http://%s%s\" %s\n" "$date" "$method" "$host" "$path" "$status_length"
-			trap - INT
-			exit
-			;;
-		*)
-			;;
-		esac
-	done
-}
-
-# dependency verification
-for cmd in nc argon2 podman; do
-  command -v $cmd >/dev/null || { echo "$0: \`$cmd\` not found"; exit 2; }
-done
-
-while getopts p:h opt; do
-	case $opt in
-	p) port=$OPTARG;;
-	h) usage; exit 255;;
-	*) usage; exit 255;;
-	esac
-done
-shift $((OPTIND-1))
-
-if [ $# -eq 0 ]; then
-	docroot=.
-else
-	docroot="$1"
-fi
-docroot=$(cd "$docroot"; pwd)
-
-# FIFO to write HTTP response ## todo mktemp
-if ! fifo1=$(makefifo "${0##*/}.$$.1"); then
-	echo "$0: creating a named pipe failed.  Already running?" 1>&2
-	exit 1
-fi
-
-# FIFO for internal event notification ## todo mktemp
-if ! fifo2=$(makefifo "${0##*/}.$$.2"); then
-	echo "$0: creating a named pipe failed.  Already running?" 1>&2
-	exit 1
-fi
-
-trap interrupt INT
-
-echo $$ > "$pid_file"
-
-cat 1>&2 <<EOF
-Simple HTTP Server
-
-Listening at the port number $port.
-Type ^C to quit.
-EOF
-
-# todo nc error should crash
-# shellcheck disable=SC2002
-while cat "$fifo1" | "$nc" -l -p "$port" | parse; do
-	:
-done
-cleanup
-exit




diff --git a/toymaker.sh b/toymaker.sh
new file mode 100755
index 0000000000000000000000000000000000000000..ad646f5371ce9db4eac1b6f5fdafc1ea7de562ef
--- /dev/null
+++ b/toymaker.sh
@@ -0,0 +1,391 @@
+#!/bin/sh
+#
+# Based on server by Upper Stream (c) 2017, MIT license
+# (https://gist.github.com/upperstream/b9b77429bc024541b7605aea76086ad8)
+
+. start.sh
+. get.sh
+. password.sh
+
+set -e
+
+exec >>~/toymaker.log
+exec 2>&1
+
+# program name
+program=${0##*/}
+
+usage() {
+	cat <<-EOF
+	Usage:
+
+	$program [-p port] [docroot]
+	$program -h
+
+	-p port : specify listening port number; defaults to 1313
+	-h      : print this help and quit
+	docroot : specify document root directory; defaults to the current directory
+EOF
+}
+
+# default listening port
+port=1313
+
+# Configure in accordance with your environment
+nc=$(command -v nc) || true
+
+# todo mktmp
+pid_file=/tmp/$program.pid
+
+slashes() {
+	printf "%s" "$1" | sed 's|[^/]||g' | wc -m
+}
+
+field() {
+	echo "$1" | cut -d '/' -f "$2"
+}
+makefifo() {
+	name="$1"
+	mkfifo -m 0600 "/tmp/$name.fifo" && echo "/tmp/$name.fifo"
+}
+
+templateMessage() {
+	message=$1
+	templateName=$2
+	contentType=$3
+	case $contentType in
+		text/plain)
+			ext='txt'
+			;;
+		text/html|\*|\*/\*|'')
+			ext='html'
+			;;
+		image/\*|image/svg)
+			ext='svg'
+			;;
+		*)
+		return 1
+		;;
+	esac
+	[ -f "templates/$templateName.$ext" ] || return 1
+	#shellcheck disable=SC1090
+	. "templates/$templateName.$ext"
+	template "$message"
+}
+
+respond200() {
+	page="$1"
+	contentType="$2"
+	[ -z "$contentType" ] && contentType='text/html'
+
+	# { cat "$fifo2" > /dev/null; printf ""; } > "$fifo1" &
+
+	printf "HTTP/1.1 200 OK\r\nContent-Length: %s\r\nContent-Type: %s\r\n\r\n%s\r\n" "${#page}" "$contentType" "$page" > "$fifo1"
+
+	# printf "%s\r\n" "$page" >> "$fifo1"
+
+	# sleep 1; echo "end" > "$fifo2"
+	printf "200 %s" "${#page}"
+}
+
+respond200file() {
+	filePath="$1"
+	contentType="$2"
+
+	{ cat "$fifo2" > /dev/null; printf ""; } > "$fifo1" &
+
+	printf "HTTP/1.1 200 OK\r\nContent-Length: %s\r\nContent-Type: %s\r\n\r\n" "${#page}" "$contentType" >> "$fifo1"
+
+	cat "$filePath" >> "$fifo1"
+
+	sleep 1; echo "end" > "$fifo2"
+	printf "200 %s" "${#page}"
+}
+
+respond202() {
+	toy=$1
+	item=$2
+	message=$3
+	contentType="$4"
+	[ -z "$contentType" ] && contentType='text/html'
+	printf "HTTP/1.1 202 Accepted\r\nContent-Length: %s\r\nLocation: /toys/%s/%s\r\n\r\n%s\r\n" "${#message}" "$toy" "$item" "$message" > "$fifo1"
+	printf "202 -"
+}
+
+respond401() {
+	message=""
+	printf "HTTP/1.1 401 Unauthorized\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "401 -"
+}
+
+respond403() {
+	message=""
+	printf "HTTP/1.1 403 Forbidden\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "403 -"
+}
+
+respond404() {
+	path=$1
+	# todo html
+	message="$path not found"
+	printf "HTTP/1.1 404 Not Found\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "404 -"
+}
+
+respond405() {
+	method=$1
+	# todo html
+	message="$method unsupported"
+	printf "HTTP/1.1 405 Method Not Allowed\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "405 -"
+}
+
+respond406() {
+	contentType=$1
+	# todo html
+	message="$contentType unsupported"
+	printf "HTTP/1.1 406 Not Acceptable\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "406 -"
+}
+
+respond500() {
+	# todo html
+	message="Server error: $1"
+	printf "HTTP/1.1 500 Internal Server Error\r\nContent-Length: %s\r\n\r\n%s\r\n" "${#message}" "$message" > "$fifo1"
+	printf "500 -"
+}
+
+check_auth() {
+	authorization=$1
+	stored=$(cat password)
+	if [ -z "$stored" ] || [ -z "$authorization" ]
+	then
+		respond401
+		return 1
+	fi
+	if ! printf '%s' "$authorization" | verify "$stored"
+	then
+		respond403
+		return 1
+	fi
+}
+
+execute() {
+	method="$1"
+	path="$2"
+	authorization="$3"
+	accept="$4"
+	_toys=$(field "$path" 2)
+	if [ "$_toys" != 'toys' ]
+	then
+		respond404 "$path"
+		return 1
+	fi
+
+	case $method in
+	GET)
+		if [ "$(slashes "$path")" -eq 2 ]
+		then
+			toy=$(field "$path" 3)
+			if [ "$toy"  = '' ]
+			then
+				if page=$(templateMessage "$(list_toys)" 'toys' 'text/html')
+				then
+					respond200 "$page"
+				else
+					respond406 "$accept"
+				fi
+			else
+				r=$(list_items "$toy")
+				status=$(echo "$r" | cut -d ';' -f 1)
+				if [ "$status" = 'n' ]
+				then
+					respond404 "$path"
+				elif page=$(templateMessage "$r" 'items' 'text/html')
+				then
+					respond200 "$page"
+				else
+					respond406 "$accept"
+				fi
+			fi
+		elif [ "$(slashes "$path")" -eq 3 ]
+		then
+			toy=$(field "$path" 3)
+			item=$(field "$path" 4)
+			if [ -z "$item" ]
+			then
+				respond404 "$path"
+				return 1
+			fi
+			r=$(show_item "$toy" "$item")
+			status=$(echo "$r" | cut -d ';' -f 1)
+			if [ "$status" = 'n' ]
+			then
+				respond404 "$path"
+			elif page=$(templateMessage "$r" 'item' "$accept")
+			then
+				if [ "$status" = 'r' ]
+				then
+					respond202 "$toy" "$item" "$page" "$accept"
+				else
+					respond200 "$page" "$accept"
+				fi
+			else
+				respond406 "$accept"
+			fi
+		elif [ "$(slashes "$path")" -eq 4 ]
+		then
+			toy=$(field "$path" 3)
+			item=$(field "$path" 4)
+			artifactName=$(field "$path" 5)
+			r=$(get_artifact "$toy" "$item" "$artifactName")
+			status=$(echo "$r" | cut -d ';' -f 1)
+			if [ "$status" = 'n' ]
+			then
+				respond404 "$path"
+			else
+				contentType=$(echo "$r" | cut -d ';' -f 2)
+				filePath=$(echo "$r" | cut -d ';' -f 3)
+				respond200file "$filePath" "$contentType"
+			fi
+		else
+			respond404 "$path"
+		fi
+		;;
+	POST)
+		check_auth "$authorization" || return
+
+		toy=$(field "$path" 3)
+		if [ "$(slashes "$path")" -ne 3 ] || [ -n "$(field "$path" 4)" ]
+		then
+			respond404 "$path"
+		fi
+
+		item=$(start_item "$toy")
+		if [ $! -gt 0 ]
+		then
+			respond500 "error while creating $toy"
+		else
+			respond202 "$toy" "$item"
+		fi
+
+		# todo delete old items, leave 1 stable, 1 errored
+		;;
+	DELETE)
+		check_auth "$authorization" || return
+
+		if [ "$(slashes "$path")" -eq 3 ]
+		then
+			toy=$(field "$path" 3)
+			item=$(field "$path" 4)
+			if stop_item "$toy" "$item"
+			then
+				respond200 ""
+			else
+				respond500 "error while stopping $toy/$item"
+			fi
+		else
+			respond404 "$path"
+		fi
+		;;
+	*)
+		respond405 "$method"
+		;;
+	esac
+}
+
+cleanup() {
+	rm "$fifo1" "$fifo2" "$pid_file"
+}
+
+interrupt() {
+	cleanup
+	exit 0
+}
+
+parse() {
+	cr=$(printf "\r")
+	while read -r line; do
+		line="${line%"$cr"}"
+		case "$line" in
+		GET*|POST*|PUT*|DELETE*|HEAD*|OPTIONS*|TRACE*)
+			# shellcheck disable=SC2086
+			set -- $line
+			method=$1
+			path=$2
+			;;
+		Host:*)
+			host=${line#Host: }
+			;;
+		Accept:*)
+			accept=${line#Accept: }
+			;;
+		Authorization:*)
+			authorization=${line#Authorization: }
+			;;
+		*:*)
+			;;
+		"")
+			date=$(date +'%d/%m/%Y:%H:%M:%S %z')
+			status_length=$(execute "$method" "$path" "$authorization" "$accept")
+			printf "%s %s \"http://%s%s\" %s\n" "$date" "$method" "$host" "$path" "$status_length"
+			trap - INT
+			exit
+			;;
+		*)
+			;;
+		esac
+	done
+}
+
+# dependency verification
+for cmd in nc argon2 podman; do
+  command -v $cmd >/dev/null || { echo "$0: \`$cmd\` not found"; exit 2; }
+done
+
+while getopts p:h opt; do
+	case $opt in
+	p) port=$OPTARG;;
+	h) usage; exit 255;;
+	*) usage; exit 255;;
+	esac
+done
+shift $((OPTIND-1))
+
+if [ $# -eq 0 ]; then
+	docroot=.
+else
+	docroot="$1"
+fi
+docroot=$(cd "$docroot"; pwd)
+
+# FIFO to write HTTP response ## todo mktemp
+if ! fifo1=$(makefifo "${0##*/}.$$.1"); then
+	echo "$0: creating a named pipe failed.  Already running?" 1>&2
+	exit 1
+fi
+
+# FIFO for internal event notification ## todo mktemp
+if ! fifo2=$(makefifo "${0##*/}.$$.2"); then
+	echo "$0: creating a named pipe failed.  Already running?" 1>&2
+	exit 1
+fi
+
+trap interrupt INT
+
+echo $$ > "$pid_file"
+
+cat 1>&2 <<EOF
+Simple HTTP Server
+
+Listening at the port number $port.
+Type ^C to quit.
+EOF
+
+# todo nc error should crash
+# shellcheck disable=SC2002
+while cat "$fifo1" | "$nc" -l -p "$port" | parse; do
+	:
+done
+cleanup
+exit