From: Paul Hänsch Date: Thu, 21 Jun 2018 14:00:29 +0000 (+0200) Subject: forking cgilite into separate project X-Git-Url: http://git.plutz.net/?p=cgilite;a=commitdiff_plain;h=3fdb8e7e2ed8fcf3129de33147d1dd3b4a204b21 forking cgilite into separate project --- diff --git a/cgi.sh b/cgi.sh deleted file mode 100755 index f79d416..0000000 --- a/cgi.sh +++ /dev/null @@ -1,147 +0,0 @@ -#!/bin/zsh - -# Copyright 2014 - 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 _GET _POST _REF _COOKIE -declare -A _GET -declare -A _POST -declare -A _REF -declare -A _COOKIE - -[ -z "$HTTP_REFERER" ] && HTTP_REFERER="./" - -# parse HTTP GET string -debug "== CGI DATA: GET ==" -printf '%s\n' "$QUERY_STRING" |tr '&' '\n' |while read query; do - key="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\1:')" - val="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\2:')" - _GET[$key]="$(printf "$(printf %s "$val" |sed 's:+: :g;s:\\:\\\\:g;s:%:\\x:g')")" - debug "_GET[$key] => $val" -done - -if [ "$REQUEST_METHOD" = POST -a "${HTTP_CONTENT_LENGTH:=$CONTENT_LENGTH}" -gt 0 ]; then - # parse HTTP POST string - debug "== CGI DATA: POST ==" - head -c "$HTTP_CONTENT_LENGTH" \ - | sed -un 's;&;\n;g; p; q' \ - | while read query; do - key="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\1:')" - val="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\2:')" - value="$(printf "$(printf %s "$val" |sed 's:+: :g;s:\\:\\\\:g;s:%:\\x:g;')")" - n='' - if [ -n "${_POST[$key$n]+x}" ]; then - n=0 - while [ -n "${_POST[$key$n]+x}" ]; do n=$(($n + 1)); done - fi - _POST[$key$n]="$value" - debug "_POST[$key$n] => $value" - done -fi - -cgi_refdata() { # Parse GET data from referer - debug "== CGI DATA: REFERER ==" - printf '%s\n' "${HTTP_REFERER#*\?}" |tr '&' '\n' |while read query; do - key="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\1:')" - val="$(printf %s "$query" |sed -r 's:^([\.a-zA-Z0-9_-]+)=(.*)$:\2:')" - _REF[$key]="$(printf "$(printf %s "$val" |sed 's:+: :g;s:\\:\\\\:g;s:%:\\x:g')")" - debug "_REF[$key] => $val" - done -} - -cgi_cookie() { # Parse GET data from referer - debug "== CGI DATA: COOKIE ==" - printf '%s\n' "$HTTP_COOKIE" |tr ';' '\n' |while read query; do - key="$(printf %s "$query" |sed -r 's:^ *([\.a-zA-Z0-9_-]+)=(.*)$:\1:')" - val="$(printf %s "$query" |sed -r 's:^ *([\.a-zA-Z0-9_-]+)=(.*)$:\2:')" - _COOKIE[$key]="$(printf "$(printf %s "$val" |sed 's:+: :g;s:\\:\\\\:g;s:%:\\x:g')")" - debug "_COOKIE[$key] => $val" - done -} - -htmlsafe(){ - # escape HTML code from string - - printf %s "$*" \ - | sed 's;&;\&\;;g; - s;<;\<\;;g; - s;>;\>\;;g; - s;";\"\;;g; - s;/;\/\;;g; - s;'\'';\'\;;g;' -} - -urlsafe(){ - # Code every character in URL escape hex format - # except alphanumeric ascii - - printf %s "$*" \ - | hexdump -v -e '/1 ",%02X"' \ - | tr , % \ - | sed 's;%30;0;g; s;%31;1;g; s;%32;2;g; s;%33;3;g; s;%34;4;g; s;%35;5;g; - s;%36;6;g; s;%37;7;g; s;%38;8;g; s;%39;9;g; - s;%41;A;g; s;%42;B;g; s;%43;C;g; s;%44;D;g; s;%45;E;g; s;%46;F;g; - s;%47;G;g; s;%48;H;g; s;%49;I;g; s;%4A;J;g; s;%4B;K;g; s;%4C;L;g; - s;%4D;M;g; s;%4E;N;g; s;%4F;O;g; s;%50;P;g; s;%51;Q;g; s;%52;R;g; - s;%53;S;g; s;%54;T;g; s;%55;U;g; s;%56;V;g; s;%57;W;g; s;%58;X;g; - s;%59;Y;g; s;%5A;Z;g; - s;%61;a;g; s;%62;b;g; s;%63;c;g; s;%64;d;g; s;%65;e;g; s;%66;f;g; - s;%67;g;g; s;%68;h;g; s;%69;i;g; s;%6A;j;g; s;%6B;k;g; s;%6C;l;g; - s;%6D;m;g; s;%6E;n;g; s;%6F;o;g; s;%70;p;g; s;%71;q;g; s;%72;r;g; - s;%73;s;g; s;%74;t;g; s;%75;u;g; s;%76;v;g; s;%77;w;g; s;%78;x;g; - s;%79;y;g; s;%7A;z;g; s;%2D;-;g; s;%2E;.;g; s;%2F;/;g; s;%5F;_;g' -} - -attribsafe(){ - # Code every character in HTML escape hex format - # except alphanumerig ascii - - printf %s "$*" \ - | iconv -f utf-8 -t utf32le \ - | hexdump -v -e '/4 "&#x%02X;"' \ - | sed 's;0\;;0;g; s;1\;;1;g; s;2\;;2;g; s;3\;;3;g; s;4\;;4;g; s;5\;;5;g; - s;6\;;6;g; s;7\;;7;g; s;8\;;8;g; s;9\;;9;g; - s;A\;;A;g; s;B\;;B;g; s;C\;;C;g; s;D\;;D;g; s;E\;;E;g; s;F\;;F;g; - s;G\;;G;g; s;H\;;H;g; s;I\;;I;g; s;J\;;J;g; s;K\;;K;g; s;L\;;L;g; - s;M\;;M;g; s;N\;;N;g; s;O\;;O;g; s;P\;;P;g; s;Q\;;Q;g; s;R\;;R;g; - s;S\;;S;g; s;T\;;T;g; s;U\;;U;g; s;V\;;V;g; s;W\;;W;g; s;X\;;X;g; - s;Y\;;Y;g; s;Z\;;Z;g; - s;a\;;a;g; s;b\;;b;g; s;c\;;c;g; s;d\;;d;g; s;e\;;e;g; s;f\;;f;g; - s;g\;;g;g; s;h\;;h;g; s;i\;;i;g; s;j\;;j;g; s;k\;;k;g; s;l\;;l;g; - s;m\;;m;g; s;n\;;n;g; s;o\;;o;g; s;p\;;p;g; s;q\;;q;g; s;r\;;r;g; - s;s\;;s;g; s;t\;;t;g; s;u\;;u;g; s;v\;;v;g; s;w\;;w;g; s;x\;;x;g; - s;y\;;y;g; s;z\;;z;g;' -} - -redirect(){ - printf 'Status: 303 See Other\r\nLocation: %s\r\n\r\n' "$*" - 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' -} diff --git a/debug.sh b/debug.sh deleted file mode 100755 index 259407b..0000000 --- a/debug.sh +++ /dev/null @@ -1,39 +0,0 @@ -#!/bin/zsh - -# Copyright 2014, 2015 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 . - -# put debug options in the local.opts file -DBG_ENABLED=false -DBG_FILE=/dev/stderr - -# basic functions -debug() { #change to false to disable debugging - if [ "$DBG_ENABLED" = true -a -n "$*" ]; then - printf '%s\n' "$*" >>"$DBG_FILE" - elif [ "$DBG_ENABLED" = true -a -z "$*" ]; then - tee -a "$DBG_FILE" - elif [ -z "$*" ]; then - cat - fi -} - -die() { - debug FATAL: "$*" - printf '%s\n' "$*" >&2 - exit 1 -} diff --git a/files.sh b/files.sh deleted file mode 100755 index bf8b7b9..0000000 --- a/files.sh +++ /dev/null @@ -1,73 +0,0 @@ -#!/bin/sh - -# Copyright 2018 Paul Hänsch -# -# This is a file format helper, part of CGIlite. -# -# 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 -case "${0##*/}" in - zsh) setopt -o OCTAL_ZEROES 2>&- ;; # zsh, mostly ignored by other shells - ksh) set -o posix ;; # ksh, will crash most other shells -esac - -STORE(){ - # Store fields from a HTTP GET or POST string in a file - # usage: STORE "${QUERY_STRING}" - # or: STORE "$(head -n $HTTP_CONTENT_LENGTH)" - # backslashes and newline characters will be escaped in field values, - # the escape symbol is a backslash - # hexadecimal character descriptions (%00 - %FF) will be expanded - # the + character will be converted to [space] - # one line in the output corresponds to exactly one field, so you can - # use grep to filter which fields of a query should be stored - printf "$( - printf '%s' "$@" \ - | sed -r ':X; $bY; N; bX; :Y; - s;\+; ;g; s;(\\|5[Cc]);\\\\\\\\;g; s;(\n|%0[Aa]);\\\\n;g; s;(^|&)([^=]+)=;\1\2:;g; s;&;\n;g; - s;^\n+;;; s;$;\\n;; s;\n+;\n;g; - # Hexadecimal { %00 - %FF } will be transformed to octal { \000 - \377 } for posix printf - s;%[0123].;&\\0;g; s;%[4567].;&\\1;g; s;%[89AB].;&\\2;g; s;%[CDEF].;&\\3;g; - s;%[048C][0-7]\\.;&0;g; s;%[048C][89A-F]\\.;&1;g; s;%[159D][0-7]\\.;&2;g; s;%[159D][89A-F]\\.;&3;g; - s;%[26AE][0-7]\\.;&4;g; s;%[26AE][89A-F]\\.;&5;g; s;%[37BF][0-7]\\.;&6;g; s;%[37BF][89A-F]\\.;&7;g; - s;%.[08](\\..);\10;g; s;%.[19](\\..);\11;g; s;%.[2A](\\..);\12;g; s;%.[3B](\\..);\13;g; - s;%.[4C](\\..);\14;g; s;%.[5D](\\..);\15;g; s;%.[6E](\\..);\16;g; s;%.[7F](\\..);\17;g; - ' - )" -} - -LOAD(){ - # read a file written by STORE and assign all fields to variables - # usage: eval "$(LOAD . - -# ksh and zsh workaround -# set -o posix # ksh, not portable -setopt -o OCTAL_ZEROES 2>&- - -form_radio(){ - # Usage: form_radio Name Value Condition Label - # if "Condition" is the same as "Value", the button will be checked - - name="$1" - value="$2" - cond="$3" - label="$4" - id="rd_${name}_${value}" - - [ "$value" = "$cond" ] && check='checked="checked"' || check='' - - printf '' \ - "$id" "$name" "$value" "$check" "$id" "$label" -} - -form_check(){ - # Usage: form_check Name Value Condition Label - # if "Condition" is the same as "Value", the Checkbox will be checked - - name="$1" - value="$2" - cond="$3" - label="$4" - id="rd_${name}_${value}" - - [ "$value" = "$cond" ] && check='checked="checked"' || check='' - - printf '' \ - "$id" "$name" "$value" "$check" "$id" "$label" -} diff --git a/htaccess.example b/htaccess.example deleted file mode 100644 index 2c8b66e..0000000 --- a/htaccess.example +++ /dev/null @@ -1,3 +0,0 @@ -Options +ExecCGI -AddHandler cgi-script .cgi -DirectoryIndex index.cgi diff --git a/index.cgi b/index.cgi deleted file mode 100755 index 907041e..0000000 --- a/index.cgi +++ /dev/null @@ -1,62 +0,0 @@ -#!/bin/zsh - -# Copyright 2014 - 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 . - -export LC_ALL=C LANG=C - -# this program is supposed to be symlinked into a http root directory -# we will use the http root as object storage (data directory) and call sub -# programs from the directory in which the real executable resides -# therefore we need to identify the code and data directories _EXEC and _DATA -call="$0" -real="$(readlink -f $call)" -export _DATA="$(dirname "$call")" #storage directory -export _EXEC="${real%/shcgi/index.cgi}" #execution directory - -# put debug options in the local.opts file -. "$_EXEC/shcgi/misc.sh" -. "$_EXEC/shcgi/debug.sh" -[ -r "$_DATA/local.opts" ] && . "$_DATA/local.opts" - -if [ "$1" = '--server' -o "$1" = '--inetd' -o "$1" = '--ncat' ]; then - . "$_EXEC/shcgi/server.sh" $@ -else - HTTP_format(){ cat } -fi - -. "$_EXEC/shcgi/cgi.sh" - -[ -x "$_EXEC/globals.sh" ] && . "$_EXEC/globals.sh" - - PAGE=$(validate "${PAGE:-${_GET[page]}}" '[a-zA-Z0-9_-]+' '') -ACTION=$(validate "${ACTION:-${_GET[action]}}" '[a-zA-Z0-9_-]+' '') -STATIC=$(invalidate "${STATIC:-${_GET[static]}}" '(^|.*/)\.\./.*' '') - -if [ -n "$STATIC" ] && [ -e "${_EXEC}/static/${STATIC}" ]; then - . "$_EXEC/shcgi/static.sh" "$_EXEC/static/$STATIC" -elif [ -n "$ACTION" ] && [ -x "${_EXEC}/actions/${ACTION}.sh" ]; then - . "${_EXEC}/actions/${ACTION}.sh" -elif [ -n "$PAGE" ] && [ -x "${_EXEC}/pages/${PAGE}.sh" ]; then - . "$_EXEC/shcgi/page.sh" -else - printf 'Status: 404 Not Found\r\n' - PAGE=error - [ -x "${_EXEC}/pages/${PAGE}.sh" ] \ - && . "$_EXEC/shcgi/page.sh" \ - || printf '\r\n' -fi |HTTP_format $@ diff --git a/local.opts b/local.opts deleted file mode 100644 index a473b58..0000000 --- a/local.opts +++ /dev/null @@ -1,8 +0,0 @@ -# This file is meaningless in the exec directory -# You can copy it to your data directory (usually -# your HTTP root) to set per instance debug -# options and the like -# beware that the file is sourced as a shell script - -DBG_ENABLED=false -DBG_FILE=/dev/stderr diff --git a/misc.sh b/misc.sh deleted file mode 100755 index 9639309..0000000 --- a/misc.sh +++ /dev/null @@ -1,54 +0,0 @@ -#!/bin/zsh - -# Copyright 2014 - 2017 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 . - -BR=' -' - -data_dirs(){ - # set up directories for object storage - - [ -d "$_DATA" -a -w "$_DATA" ] || die "storage directory must be writable" - for each in "$@"; do - [ ! -e "$_DATA/$each" ] && mkdir "$_DATA/$each" - [ -d "$_DATA/$each" -a -w "$_DATA/$each" ] || die "storage \"$_DATA/$each\" must be a writable directory" - done -} - -validate(){ - # print value if value matches regex; otherwise print default - value="$1" - regex="$2" - default="$3" - - printf %s "${value%%${BR}*}" |grep -xE "$regex" || printf %s "$default" -} - -invalidate(){ - # print default if value matches regex; otherwise print value - value="$1" - regex="$2" - default="$3" - - printf %s "${value%%${BR}*}" |grep -qxE "$regex" && printf %s "$default" || printf %s "${value%%${BR}*}" -} - -declare -A item_name -l10n(){ - [ -n "${item_name[$1]+x}" ] && printf %s "$item_name[$1]" || printf %s "$1" -} diff --git a/page.sh b/page.sh deleted file mode 100755 index def7280..0000000 --- a/page.sh +++ /dev/null @@ -1,33 +0,0 @@ -#!/bin/zsh - -# Copyright 2014 - 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 . - -. "${_EXEC}/shcgi/forms.sh" - -[ -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}" - -. "${_EXEC}/pages/${PAGE}.sh" - -# prevent browsers from caching generated pages -printf "Cache-Control: no-cache, no-store, must-revalidate\r\nPragma: no-cache\r\nExpires: 0\r\n" -printf "Content-Type: text/html;charset=utf-8\r\n\r\n" -. "${_EXEC}/templates/frame.html.sh" diff --git a/server.sh b/server.sh deleted file mode 100755 index c49c0d8..0000000 --- a/server.sh +++ /dev/null @@ -1,99 +0,0 @@ -#!/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 . - -if [ "$1" = '--server' ]; then - shift 1 - ncat -klc "$call --ncat" $@ - exit $? -fi - -export REMOTE_ADDR="${NCAT_REMOTE_ADDR}" -export SERVER_NAME="${NCAT_LOCAL_ADDR}" -export SERVER_PORT="${NCAT_LOCAL_PORT}" - -eval $( -sed -unr ' - w/dev/stderr - /^(GET|HEAD|POST) ([^\?]*)\??(.+)? (HTTP\/[0-9]\.[0-9])\r?$/{ - h - s;^(GET|HEAD|POST) ([^\?]*)\??(.+)? (HTTP\/[0-9]\.[0-9])\r?$;export REQUEST_METHOD='\''\1'\'';p - g - s;^(GET|HEAD|POST) ([^\?]*\??.*) (HTTP\/[0-9]\.[0-9])\r?$;\2; - s;'\'';'\''\\'\'''\'';g - s;^.*$;export REQUEST_URI='\''&'\'';p - g - s;^(GET|HEAD|POST) ([^\?]*)\??(.+)? (HTTP\/[0-9]\.[0-9])\r?$;\2; - s;'\'';'\''\\'\'''\'';g - s;^.*$;export PATH_INFO='\''&'\'';p - g - s;^(GET|HEAD|POST) ([^\?]*)\??(.+)? (HTTP\/[0-9]\.[0-9])\r?$;\3; - s;'\'';'\''\\'\'''\'';g - s;^.*$;export QUERY_STRING='\''&'\'';p - g - s;^(GET|HEAD|POST) ([^\?]*)\??(.+)? (HTTP\/[0-9]\.[0-9])\r?$;export SERVER_PROTOCOL='\''\4'\'';p - g - } - - /^[Pp][Rr][Oo][Xx][Yy]: /d - - /^[a-zA-Z_-]+: .*$/{ - h - s;^[^:]+: (.*)\r$;\1; - s;'\'';'\''\\'\'''\'';g - s;^.*$;'\''&'\''; - x - s;: .*$;; - y;abcdefghijklmnopqrstuvwxyz-;ABCDEFGHIJKLMNOPQRSTUVWXYZ_; - s;^.+$;export HTTP_&=; - G - s;\n;; - p - } - /^\r?$/q -' -) - -HTTP_format(){ - LC_ALL=C sed -urn ' - :A - /^\r?$/!{H;n;bA} - - g - s;^(\r?\n)*;;; - s;([^\r])\n;\1\r\n;g; - aConnection: close\r\n\r - /^Status: *[1-5][0-9][0-9] .*/{s;^Status: *;HTTP/1.1 ;; bX} - s;^(.+\n)?Location: .*$;HTTP/1.1 302 Found\r\n&; - s;^(.+\n)?Content-Type: .*$;HTTP/1.1 200 OK\r\n&; - - :X - p - $q - n - bX - ' -} - - -if [ -z "$QUERY_STRING" ]; then - PATH_INFO="$(printf "$(printf %s "$PATH_INFO" |sed 's:+: :g;s:\\:\\\\:g;s:%:\\x:g')")" - PATH_INFO="$(invalidate "${PATH_INFO}" '(^|.*/)\.\./.*' '')" - [ -f "${treeroot:-${_DATA}}/$PATH_INFO" ] && . "$_EXEC/shcgi/static.sh" "${treeroot:-${_DATA}}/$PATH_INFO" - exit 0 -fi |HTTP_format diff --git a/static.sh b/static.sh deleted file mode 100755 index bf109ed..0000000 --- a/static.sh +++ /dev/null @@ -1,67 +0,0 @@ -#!/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 suffix -file="$1" -date="$(stat -Lc %Y "$file")" - -# allow overriding magic file recognition -# don't use this if `file` returns type correctly -declare -A suffix -suffix[css]="text/css" - -[ -n "$HTTP_IF_MODIFIED_SINCE" ] && cachedate="$(date -d "$HTTP_IF_MODIFIED_SINCE" +%s)" - -if printf '%s' "${HTTP_RANGE}" |grep -qE '^bytes=[0-9]+-[0-9]*\r?$'; then - _range="${HTTP_RANGE#bytes=}" - _bstart="${_range%-*}" - _bend="${_range#*-}" -fi - -if ! [ -f "$file" ] || [ -x "$file" ] || ! grep -qm1 '' "$file" ; then - printf 'Status:403 Forbidden\r\n\r\n' -elif [ "$date" = "$cachedate" ]; then - printf 'Status:304 Not Modified\r\n' - printf 'Last-Modified: %s\r\n\r\n' "$(date -Rd "@$date")" -elif [ "$_bstart" -gt 0 ] ; then - length="$(stat -Lc %s "$file")" - magic="${suffix[${file##*.}]:-$(file -bi "$file")}" - - printf 'Status:206 Partial Content\r\n' - printf 'Last-Modified: %s\r\n' "$(date -Rd "@$date")" - printf 'Content-Type: %s\r\n' "${magic:-all/all}" - printf 'Content-Range: bytes %i-%i/%i\r\n' $_bstart $(($length - 1)) $length |debug - printf 'Content-Length: %i\r\n' $(($length - $_bstart)) - printf '\r\n' - - tail -c+"$(($_bstart + 1))" "$file" -else - length="$(stat -Lc %s "$file")" - magic="${suffix[${file##*.}]:-$(file -bi "$file")}" - - printf 'Accept-Ranges: bytes\r\n' - printf 'Last-Modified: %s\r\n' "$(date -Rd "@$date")" - printf 'Content-Type: %s\r\n' "${magic:-all/all}" - printf 'Content-Length: %i\r\n' "$length" - printf '\r\n' - - cat "$file" -fi -