From: paul Date: Sun, 10 Apr 2016 21:43:20 +0000 (+0000) Subject: support static file serving; support null-string default in validate functions X-Git-Url: https://git.plutz.net/?a=commitdiff_plain;h=456423f02f12ac71d2d14e1abf959dafdc5eb041;p=cgilite support static file serving; support null-string default in validate functions svn path=/trunk/; revision=24 --- diff --git a/action.sh b/action.sh deleted file mode 100755 index caf214c..0000000 --- a/action.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/zsh - -# Copyright 2014 Paul Hänsch -# -# This file is part of Serve0. -# -# Serve0 is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# Serve0 is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with Serve0. If not, see . - -ACTION="$(printf %s "${_GET[action]}" |egrep '^[a-zA-Z0-9_-]+$')" -ACTION="${_EXEC}/actions/${ACTION}.sh" - -if [ -x "$ACTION" ]; then - debug "trying to execute $ACTION" - . $ACTION -else - debug "unable to execute $ACTION" - printf "Location: ?p=error\n\n" -fi - diff --git a/index.cgi b/index.cgi index b406bc9..92ccfd6 100755 --- a/index.cgi +++ b/index.cgi @@ -1,6 +1,6 @@ #!/bin/zsh -# Copyright 2014, 2015 Paul Hänsch +# Copyright 2014 - 2016 Paul Hänsch # # This file is part of shcgi. # @@ -29,6 +29,7 @@ _DATA="$(dirname "$call")" #storage directory _EXEC="${real%/shcgi/index.cgi}" #execution directory . "$_EXEC/shcgi/misc.sh" + # put debug options in the local.opts file . "$_EXEC/shcgi/debug.sh" [ -r "$_DATA/local.opts" ] && . "$_DATA/local.opts" @@ -37,8 +38,18 @@ _EXEC="${real%/shcgi/index.cgi}" #execution directory [ -x "$_EXEC/globals.sh" ] && . "$_EXEC/globals.sh" -if [ -n "${_GET[action]}" ]; then - . "$_EXEC/shcgi/action.sh" + PAGE=$(validate "${PAGE:-${_GET[page]}}" '[a-zA-Z0-9_-]+' '') +ACTION=$(validate "${ACTION:-${_GET[action]}}" '[a-zA-Z0-9_-]+' '') +STATIC=$(validate "${STATIC:-${_GET[static]}}" '[^\.]+' '') + +if [ -n "$PAGE" -a -x "${_EXEC}/pages/${PAGE}.sh" ]; then + . "$_EXEC/shcgi/page.sh" +elif [ -n "$ACTION" -a -x "${_EXEC}/actions/${ACTION}.sh" ]; then + . "${_EXEC}/actions/${ACTION}.sh" +elif [ -n "$STATIC" -a -e "${_EXEC}/static/${STATIC}" ]; then + . "$_EXEC/shcgi/static.sh" else + printf 'HTTP/1.1 404 Not Found\r\n' + PAGE=error . "$_EXEC/shcgi/page.sh" fi diff --git a/misc.sh b/misc.sh index 54c3dc6..19997d4 100755 --- a/misc.sh +++ b/misc.sh @@ -30,25 +30,25 @@ data_dirs(){ validate(){ # print value if value matches regex; otherwise print default value="$1" - regex="$(printf %s\\n "$2" \ - | sed -r 's;(^|[^\\]+)((\\\\)+)/;\1\2\\/;g; s;(^|[^\\])/;\1\\/;g; s;(^|[^\\]+)((\\\\)+)/;\1\2\\/;g; s;(^|[^\\])/;\1\\/;g;' - )" # ^^ escape only unescaped slash characters for later insertion + regex="$(printf %s\\n "$2" | sed -r ':X;s;(^|[^\\])((\\\\)*)/;\1\2\\/;g;tX')" + # ^^ escape only unescaped slash characters for later insertion default="$3" printf %s\\n "${value}" \ - | sed -rn "2q; /^(${regex})\$/{p;q}; a${default}" + | sed -rn "2q; /^(${regex})\$/{p;q}; a${default} + " } invalidate(){ # print default if value matches regex; otherwise print value value="$1" - regex="$(printf %s\\n "$2" \ - | sed -r 's;(^|[^\\]+)((\\\\)+)/;\1\2\\/;g; s;(^|[^\\])/;\1\\/;g; s;(^|[^\\]+)((\\\\)+)/;\1\2\\/;g; s;(^|[^\\])/;\1\\/;g;' - )" # ^^ escape only unescaped slash characters for later insertion + regex="$(printf %s\\n "$2" | sed -r ':X;s;(^|[^\\])((\\\\)*)/;\1\2\\/;g;tX')" + # ^^ escape only unescaped slash characters for later insertion default="$3" printf %s\\n "${value}" \ - | sed -rn "2q; /^(${regex})\$/{bd}; p;q; :d;a${default}" + | sed -rn "2q; /^(${regex})\$/{bX}; p;q; :X;a${default} + " } declare -A item_name diff --git a/page.sh b/page.sh index cb1b87f..94d864d 100755 --- a/page.sh +++ b/page.sh @@ -19,10 +19,8 @@ printf "Content-Type: text/html;charset=utf-8\n\n" -PAGE=$(validate "${PAGE:-${_GET[page]}}" '[a-zA-Z0-9_-]+' error) -[ -x "${_EXEC}/pages/${PAGE}.sh" ] || PAGE="error" - -[ -z "$NAVIGATION" ] && NAVIGATION=($(printf %s\\n "${_EXEC}"/pages/*.sh |sed -r 's;^.*/([^/]*)\.sh$;\1;')) +[ -z "$NAVIGATION" ] \ +&& NAVIGATION=($(printf %s\\n "${_EXEC}"/pages/*.sh |sed -r 's;^.*/([^/]*)\.sh$;\1;')) CSS="${CSS:-${_EXEC}/templates/${PAGE}.css.sh}" BODY="${BODY:-${_EXEC}/templates/${PAGE}.html.sh}" diff --git a/static.sh b/static.sh new file mode 100755 index 0000000..c86ed9f --- /dev/null +++ b/static.sh @@ -0,0 +1,40 @@ +#!/bin/zsh + +# Copyright 2016 Paul Hänsch +# +# This file is part of shcgi. +# +# shcgi is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as published by +# the Free Software Foundation, either version 3 of the License, or +# (at your option) any later version. +# +# shcgi is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with shcgi. If not, see . + + +unset length date file +file="$_EXEC/static/$STATIC" +date="$(stat -c %Y "$file")" + +if [ -x "$file" -o \! -r "$file" -o \! -f "$file" ]; then + printf 'HTTP/1.1 403 Forbidden\n\n' +elif [ "$date" = "$HTTP_IF_NONE_MATCH" ]; then + printf 'HTTP/1.1 304 Not Modified\n\n' +else + length="$(stat -c %s "$file")" + magic="$(file -bi "$file")" + + printf 'Etag: %s\r\n' "$date" + printf 'Content-Type: %s\r\n' "${magic:-all/all}" + printf 'Content-Length: %s\r\n' "$length" + printf '\r\n' + + cat "$file" +fi +