From: paul Date: Mon, 15 May 2017 05:42:01 +0000 (+0000) Subject: posix collection of chi functions, initial commit X-Git-Url: https://git.plutz.net/?a=commitdiff_plain;h=df71d6cb43c25034a8922e02b5bb86adb1118d01;p=shcgi posix collection of chi functions, initial commit svn path=/trunk/; revision=54 --- diff --git a/cgilite.sh b/cgilite.sh new file mode 100755 index 0000000..8a2ee57 --- /dev/null +++ b/cgilite.sh @@ -0,0 +1,129 @@ +#!/bin/sh + +# Copyright 2017 Paul Hänsch +# +# This is CGIlite. +# A collection of posix shell functions for writing CGI scripts. +# +# CGIlite 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. +# +# CGIlite 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 CGIlite. If not, see . + +# ksh and zsh workaround +set -o posix -o OCTAL_ZEROES 2>&- + +if [ "$REQUEST_METHOD" = POST -a "${HTTP_CONTENT_LENGTH:=${CONTENT_LENGTH:=0}}" -gt 0 ]; then + cgilite_post="$(head -c "$HTTP_CONTENT_LENGTH")" +fi + +cgilite_count(){ + printf "$( + case $1 in + GET) printf %s "${QUERY_STRING}";; + POST) printf %s "?${cgilite_post}";; + REF) printf %s "?${HTTP_REFERER#*\?}";; + esac \ + | grep -Eo '[&?]'"$2"'=[^&]*' \ + | wc -l + )" +} + +cgilite_value(){ + printf "$( + case $1 in + GET) printf %s "${QUERY_STRING}";; + POST) printf %s "?${cgilite_post}";; + REF) printf %s "?${HTTP_REFERER#*\?}";; + esac \ + | grep -Eo '[&?]'"$2"'=[^&]*' \ + | sed -rn "${3:-1}"'{s;^[^=]+=;;; s;\+; ;g; s;\\;\\\\;g; s;%;\\x;g; p}' + )" +} + +GET(){ + cgilite_value GET $@ +} +GET_no(){ + cgilite_count GET $1 +} + +POST(){ + cgilite_value POST $@ +} +POST_no(){ + cgilite_count POST $1 +} + +REF(){ + cgilite_value REF $@ +} +REF_no(){ + cgilite_count REF $1 +} + +COOKIE(){ + printf "$( + printf %s " ${HTTP_COOKIE}" \ + | grep -Eo '[; ]'"$1"'=[^;]*' \ + | sed -rn "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; s;\\;\\\\;g; s;%;\\x;g; p}' + )" +} + +HTMLEC(){ + # HTML Entity Coding + # Prints UTF-8 string as decimal Unicode Code Points + # Useful for escaping user input for use in HTML text and attributes + printf %s "$*" \ + | hexdump -ve '/1 "%03o\n"' \ + | while read n; do + case $n in + [01]??) printf '0000%s' $n;; + 2??) printf '%s' ${n#2};; + 3[0123]?) printf '000%s' ${n#3};; + 34?) printf '00%s' ${n#34};; + 35?) printf '01%s' ${n#35};; + 36?) printf '%s' ${n#36};; + esac + done \ + | sed -r 's;.{7};&\n;g;' \ + | while read n; do + printf '&#%d;' $((0$n)) + done +} + +urlsafe(){ + # Code every character in URL escape hex format + # except alphanumeric ascii + + printf %s "$*" \ + | hexdump -v -e '/1 ",%02X"' \ + | tr , % +} + +redirect(){ + printf '%s\r\n\r\n' "Location: $(urlsafe $*)" + exit 0 +} + +set_cookie(){ + case "$1" in + session|0) expire='';; + ''|default) expire="$(LANG=C date -d "+ 1 week" +'%a, %d %b %Y %T %Z')";; + *) expire="$(LANG=C date -d "$1" +'%a, %d %b %Y %T %Z' 2>&-)";; + esac + cookie="$2" + + printf 'Set-Cookie: %s' "$cookie" + [ -n "$expire" ] && printf '; Expires=%s' "$expire" + [ $# -ge 3 ] && shift 2 && printf '; %s' "$@" + printf '\r\n' +}