X-Git-Url: https://git.plutz.net/?p=cgilite;a=blobdiff_plain;f=file.sh;h=6f956dfeb5989a6b2542534d78134bc4633217de;hp=0d1f4eabb0b7e80541c9f0271892d25ba888472f;hb=HEAD;hpb=d09c1c1448cfb0e9a28f32ee3bcda554763dbfcc diff --git a/file.sh b/file.sh index 0d1f4ea..c66b17d 100755 --- a/file.sh +++ b/file.sh @@ -1,21 +1,18 @@ #!/bin/sh -# Copyright 2016 - 2019 Paul Hänsch -# -# This file is part of cgilite. +# Copyright 2016 - 2024 Paul Hänsch # -# 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. +# Permission to use, copy, modify, and/or distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. # -# 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 . +# THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +# SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR +# IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. [ -n "$include_fileserve" ] && return 0 include_fileserve="$0" @@ -48,24 +45,32 @@ file_type(){ } FILE(){ - local file file_size file_date http_date cachedate range mime - file="$1" mime="$2" + local file="$1" mime="$2" + local file_size file_date http_date cachedate range if ! [ -f "$file" ]; then printf 'Content-Length: 0\r\nStatus: 404 Not Found\r\n\r\n' - exit 0 + return 0 elif ! [ -r "$file" ]; then printf 'Content-Length: 0\r\nStatus: 403 Forbidden\r\n\r\n' - exit 0 + return 0 fi - file_size="$(stat -Lc %s "$file")" - file_date="$(stat -Lc %Y "$file")" + read file_size file_date <<-EOF + $(stat -Lc "%s %Y" "$file") + EOF http_date="$(date -ud "@$file_date" +"%a, %d %b %Y %T GMT")" + + [ ! "$HTTP_IF_MODIFIED_SINCE" -a "$cgilite_headers" ] \ + && HTTP_IF_MODIFIED_SINCE="$(HEADER If-Modified-Since)" + [ ! "$HTTP_RANGE" -a "$cgilite_headers" ] \ + && HTTP_RANGE="$(HEADER Range)" + cachedate="$( # Parse the allowable date formats from Section 3.3.1 of # https://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html - HEADER If-Modified-Since \ + # HEADER If-Modified-Since \ + printf %s "$HTTP_IF_MODIFIED_SINCE" \ | sed -E 's;^[^ ]+, ([0-9]{2}) (...) ([0-9]{4}) (..:..:..) GMT$;\3-\2-\1 \4;; s;^[^ ]+, ([0-9]{2})-(...)-([789][0-9]) (..:..:..) GMT$;19\3-\2-\1 \4;; s;^[^ ]+, ([0-9]{2})-(...)-([0-6][0-9]) (..:..:..) GMT$;20\3-\2-\1 \4;; @@ -76,14 +81,25 @@ FILE(){ | xargs -r0 date +%s -ud 2>&- )" - range="$(HEADER Range |sed -nE 's;^bytes=([0-9]+-[0-9]*|-[0-9]+)$;\1;p;q;')" + range="${HTTP_RANGE#bytes=}" case "$range" in - *-) range="${range}$((file_size - 1))";; - -*) [ ${range#-} -le $file_size ] \ - && range="$((file_size - ${range#-}))-$((file_size - 1))" \ - || range="0-$((file_size - 1))";; - *-*) [ ${range#*-} -ge $file_size ] \ - && range="${range%-*}-$((file_size - 1))";; + *[!0-9]*-*|*-*[!0-9]*) + range="" + ;; + *-) + range="${range}$((file_size - 1))" + ;; + -*) + [ ${range#-} -le $file_size ] \ + && range="$((file_size - ${range#-}))-$((file_size - 1))" \ + || range="0-$((file_size - 1))" + ;; + *-*) + [ ${range#*-} -ge $file_size ] \ + && range="${range%-*}-$((file_size - 1))" + ;; + *) range="" + ;; esac if [ "$file_date" -lt "$cachedate" ] 2>&-; then