X-Git-Url: http://git.plutz.net/?p=cgilite;a=blobdiff_plain;f=cgilite.sh;h=1d8d30a5af91eff5d65fb6bc60e116525a837708;hp=3212137e68bcb262b338256d29b29d952c3ca9d1;hb=73550e0247498915aa12b719aede6214f997653c;hpb=2509a90ca35ffada128256670abf1d5c315ef6ce diff --git a/cgilite.sh b/cgilite.sh index 3212137..1d8d30a 100755 --- a/cgilite.sh +++ b/cgilite.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright 2017 - 2018 Paul Hänsch +# Copyright 2017 - 2020 Paul Hänsch # # This is CGIlite. # A collection of posix shell functions for writing CGI scripts. @@ -31,8 +31,10 @@ HEADER(){ # Read value of header line. Use this instead of # referencing HTTP_* environment variables. if [ -n "${cgilite_headers+x}" ]; then - printf %s "$cgilite_headers" \ - | sed -rn 's;^'"${1}"': ([^\r]+)\r?$;\1;i; tX; d; :X;p;q;' + local h="${BR}${cgilite_headers}" + [ "${h##*${BR}${1}: }" = "${h}" ] && return 1 + h="${h##*${BR}${1}: }" h="${h%%${BR}*}" + printf %s "${h%${CR}}" else eval "printf %s \"\$HTTP_$(printf %s "${1}" |tr a-z A-Z |tr -c A-Z _)\"" fi @@ -49,7 +51,7 @@ HEX_DECODE=' ' HEX_DECODE(){ - printf -- "$(printf %s "$1" |sed -r "$HEX_DECODE")" + printf -- "$(printf %s "$1" |sed -E "$HEX_DECODE")" } if [ -z "$REQUEST_METHOD" ]; then @@ -71,9 +73,13 @@ if [ -z "$REQUEST_METHOD" ]; then kill $cgilite_watchdog PATH_INFO="$(HEX_DECODE "${REQUEST_URI%\?*}")" QUERY_STRING="${REQUEST_URI#*\?}" - cgilite_headers="$(while read -r hl; do [ "${hl%${CR}}" ] && printf '%s\n' "$hl" || break; done )" + cgilite_headers=''; while read -r hl; do + [ "${hl%${CR}}" ] || break + cgilite_headers="${cgilite_headers}${hl}${BR}" + done - HTTP_CONTENT_LENGTH="$(HEADER Content-Length |grep -xE '[0-9]+')" + HTTP_CONTENT_LENGTH="$(HEADER Content-Length)" + HTTP_CONTENT_LENGTH="${HTTP_CONTENT_LENGTH##*[^0-9]}" export REMOTE_ADDR SERVER_NAME SERVER_PORT REQUEST_METHOD REQUEST_URI SERVER_PROTOCOL \ PATH_INFO QUERY_STRING HTTP_CONTENT_LENGTH @@ -87,15 +93,17 @@ if [ -z "$REQUEST_METHOD" ]; then . "$0" | while read -r l; do case $l in Status:*) cgilite_status="${l#Status: }";; Content-Length:*) cgilite_cl="${l}";; - $CR) printf '%s %s\r\n%s\n%s\n\r\n' \ + $CR) printf '%s %s\r\n%s%s\n\r\n' \ 'HTTP/1.1' "${cgilite_status%${CR}}" \ - "$cgilite_response" "${cgilite_cl}" - cat + "${cgilite_response}${cgilite_response:+${BR}}" "${cgilite_cl}" + cat || kill $$ [ "${cgilite_cl#Connection}" = "${cgilite_cl}" ]; exit;; - *) cgilite_response="$cgilite_response${BR}$l";; + *) cgilite_response="${cgilite_response:+${cgilite_response}${BR}}${l}";; esac; done || exit 0; (sleep $cgilite_timeout && kill $$) & cgilite_watchdog=$! done + kill $cgilite_watchdog + exit 0 fi if [ "$REQUEST_METHOD" = POST -a "${HTTP_CONTENT_LENGTH:=${CONTENT_LENGTH:=0}}" -gt 0 ]; then @@ -116,23 +124,35 @@ cgilite_value(){ str=${str#*&${name}=} cnt=$((cnt - 1)) done - printf -- "$(printf %s "${str%%&*}" |sed -r 's;\+; ;g;'"$HEX_DECODE")" + printf -- "$(printf %s "${str%%&*}" |sed -E 's;\+; ;g;'"$HEX_DECODE")" +} + +cgilite_keys(){ + local str="&$1" + while [ "${str#*&}" != "${str}" ]; do + str="${str#*&}" + printf '%s\n' "${str%%=*}" + done \ + | sort -u } GET(){ cgilite_value "${QUERY_STRING}" $@; } GET_COUNT(){ cgilite_count "${QUERY_STRING}" $1; } +GET_KEYS(){ cgilite_keys "${QUERY_STRING}"; } POST(){ cgilite_value "${cgilite_post}" $@; } POST_COUNT(){ cgilite_count "${cgilite_post}" $1; } +POST_KEYS(){ cgilite_keys "${cgilite_post}"; } REF(){ cgilite_value "${HTTP_REFERER#*\?}" $@; } REF_COUNT(){ cgilite_count "${HTTP_REFERER#*\?}" $1; } +REF_KEYS(){ cgilite_keys "${HTTP_REFERER#*\?}"; } COOKIE(){ HEX_DECODE "$( HEADER Cookie \ | grep -oE '(^|; ?)'"$1"'=[^;]*' \ - | sed -rn "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; p;}' + | sed -En "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; p;}' )" } @@ -153,7 +173,7 @@ HTML(){ 36?) printf '%s' ${n#36};; # 4 octet (21 bit) chain start esac done \ - | sed -r 's;.{7};&\n;g;' \ + | sed -E 's;.{7};&\n;g;' \ | while read n; do printf '&#%d;' $((0$n)) done @@ -170,7 +190,7 @@ URL(){ PATH(){ { [ $# -eq 0 ] && cat || printf %s "$*"; } \ - | sed -r 's;^.*$;/&/;; s;/+;/;g; + | sed -E 's;^.*$;/&/;; s;/+;/;g; :X; s;^/\.\./;/;; s;/\./;/;g; tX;