]> git.plutz.net Git - cgilite/blob - cgilite.sh
8a2ee57292a3cffe60904e337eb2d0e0b2f5518e
[cgilite] / cgilite.sh
1 #!/bin/sh
2
3 # Copyright 2017 Paul Hänsch
4 #
5 # This is CGIlite.
6 # A collection of posix shell functions for writing CGI scripts.
7
8 # CGIlite is free software: you can redistribute it and/or modify
9 # it under the terms of the GNU Affero General Public License as published by
10 # the Free Software Foundation, either version 3 of the License, or
11 # (at your option) any later version.
12
13 # CGIlite is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16 # GNU Affero General Public License for more details.
17
18 # You should have received a copy of the GNU Affero General Public License
19 # along with CGIlite.  If not, see <http://www.gnu.org/licenses/>. 
20
21 # ksh and zsh workaround
22 set -o posix -o OCTAL_ZEROES 2>&-
23
24 if [ "$REQUEST_METHOD" = POST -a "${HTTP_CONTENT_LENGTH:=${CONTENT_LENGTH:=0}}" -gt 0 ]; then
25   cgilite_post="$(head -c "$HTTP_CONTENT_LENGTH")"
26 fi
27
28 cgilite_count(){
29   printf "$(
30     case $1 in
31       GET)  printf %s "${QUERY_STRING}";;
32       POST) printf %s "?${cgilite_post}";;
33       REF)  printf %s "?${HTTP_REFERER#*\?}";;
34     esac \
35     | grep -Eo '[&?]'"$2"'=[^&]*' \
36     | wc -l
37   )"
38 }
39
40 cgilite_value(){
41   printf "$(
42     case $1 in
43       GET)  printf %s "${QUERY_STRING}";;
44       POST) printf %s "?${cgilite_post}";;
45       REF)  printf %s "?${HTTP_REFERER#*\?}";;
46     esac \
47     | grep -Eo '[&?]'"$2"'=[^&]*' \
48     | sed -rn "${3:-1}"'{s;^[^=]+=;;; s;\+; ;g; s;\\;\\\\;g; s;%;\\x;g; p}'
49   )"
50 }
51
52 GET(){
53   cgilite_value GET $@
54 }
55 GET_no(){
56   cgilite_count GET $1
57 }
58
59 POST(){
60   cgilite_value POST $@
61 }
62 POST_no(){
63   cgilite_count POST $1
64 }
65
66 REF(){
67   cgilite_value REF $@
68 }
69 REF_no(){
70   cgilite_count REF $1
71 }
72
73 COOKIE(){
74   printf "$(
75     printf %s " ${HTTP_COOKIE}" \
76     | grep -Eo '[; ]'"$1"'=[^;]*' \
77     | sed -rn "${2:-1}"'{s;^[^=]+=;;; s;\+; ;g; s;\\;\\\\;g; s;%;\\x;g; p}'
78   )"
79 }
80
81 HTMLEC(){
82   # HTML Entity Coding
83   # Prints UTF-8 string as decimal Unicode Code Points
84   # Useful for escaping user input for use in HTML text and attributes
85   printf %s "$*" \
86   | hexdump -ve '/1 "%03o\n"' \
87   | while read n; do
88     case $n in
89       [01]??) printf '0000%s' $n;;
90       2??)    printf '%s' ${n#2};;
91       3[0123]?) printf '000%s' ${n#3};;
92       34?) printf '00%s' ${n#34};;
93       35?) printf '01%s' ${n#35};;
94       36?) printf '%s' ${n#36};;
95     esac
96   done \
97   | sed -r 's;.{7};&\n;g;' \
98   | while read n; do
99     printf '&#%d;' $((0$n))
100   done
101 }
102
103 urlsafe(){
104   # Code every character in URL escape hex format
105   # except alphanumeric ascii
106
107   printf %s "$*" \
108   | hexdump -v -e '/1 ",%02X"' \
109   | tr , %
110 }
111
112 redirect(){
113   printf '%s\r\n\r\n' "Location: $(urlsafe $*)"
114   exit 0
115 }
116
117 set_cookie(){
118   case "$1" in
119     session|0)  expire='';;
120     ''|default) expire="$(LANG=C date -d "+ 1 week" +'%a, %d %b %Y %T %Z')";;
121     *)          expire="$(LANG=C date -d "$1" +'%a, %d %b %Y %T %Z' 2>&-)";;
122   esac
123   cookie="$2"
124   
125   printf 'Set-Cookie: %s' "$cookie"
126   [ -n "$expire" ] && printf '; Expires=%s' "$expire" 
127   [ $# -ge 3 ] && shift 2 && printf '; %s' "$@"
128   printf '\r\n'
129 }