blob: d04b4b1f038247c9e21c20ccd00660693073f03c (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
|
emptyok_response() {(
printf "HTTP/1.1 204 OK\r\n"
printf 'Connection: close\r\n'
printf 'Server: %s\r\n' "$Server"
printf '\r\n'
)}
not_modifed_response() {(
printf "HTTP/1.1 304 Not Modified\r\n"
printf 'Connection: close\r\n'
printf 'Server: %s\r\n' "$Server"
printf '\r\n'
)}
delete_response() {
jq -n -r \
--arg server "$Server" \
'
[ "HTTP/1.1 204 OK\r"
, "Connection: close\r"
, "Server: \($server)\r"
, "\r"
][]
'
}
file_response() {(
type=$(file -ib "$1")
size=$(wc -c < "$1")
jq -n -r \
--arg type "$type" \
--arg size "$size" \
--arg server "$Server" \
'
[ "HTTP/1.1 200 OK\r"
, "Connection: close\r"
, "Content-Length: \($size)\r"
, "Content-Type: \($type)\r"
, "Server: \($server)\r"
, "\r"
][]
'
cat "$1"
)}
read_uri() {
jq -cn --arg uri "$1" '
$uri |
capture("^((?<scheme>[^:]*):)?(//(?<authority>[^/]*))?(?<path>[^?#]*)([?](?<query>[^#]*))?([#](?<fragment>.*))?$") |
. + {
query: (.query | if . != null then
split("&") |
map(split("=") | {key:.[0],value:.[1]}) |
from_entries
else . end)
}
'
}
uri=$(read_uri "$Request_URI")
path=$(jq -nr --argjson uri "$uri" '
$uri.path |
gsub("/+"; "/")
')
case "$Method $path" in
'POST /'*|'PUT /'*)
content=$(mktemp -t htgen.$$.content.XXXXXXXX)
trap "rm $content >&2" EXIT
head -c $req_content_length > $content
item=$STATEDIR/items/$(echo "$path" | jq -rR @uri)
mkdir -v -p $STATEDIR/items >&2
cp -v $content $item >&2
emptyok_response
exit
;;
'GET /'*)
item=$STATEDIR/items/$(echo "$path" | jq -rR @uri)
if [ -e "$item" ]; then
if [ -z ${req_if_modified_since+x} ]; then
file_response "$item"
exit
else
age_file=$(date +%s -r "$item")
age_header=$(date +%s --date="$req_if_modified_since")
if [ "$age_file" -lt "$age_header" ]; then
not_modifed_response
exit
else
file_response "$item"
exit
fi
fi
fi
;;
'DELETE /'*)
item=$STATEDIR/items/$(echo "$path" | jq -rR @uri)
if [ -e "$item" ]; then
rm "$item"
delete_response
exit
fi
esac
|