]> cat aescling's git repositories - httpd-execline.git/commitdiff
reorganize configuration of resource- and domain-specific headers
authorsingle-right-quote <34298117+single-right-quote@users.noreply.github.com>
Thu, 10 Sep 2020 22:03:12 +0000 (22:03 +0000)
committersingle-right-quote <34298117+single-right-quote@users.noreply.github.com>
Thu, 10 Sep 2020 22:03:15 +0000 (22:03 +0000)
in doing so, move so-called ”extra headers” code to a separate script

furthermore, slightly adjust the logic of http-error-response.execline

headers are now specified on a per-header basis, one file per header

visible-to-httpd/binaries/http-error-response.execline
visible-to-httpd/binaries/http-get-extra-headers.execline [new file with mode: 0755]
visible-to-httpd/binaries/httpd.execline

index 0fae1983605a73eeb19756d26baf31b659cae5a8..af58267c49a06ccb233eda02176444ac4b247c2e 100755 (executable)
@@ -14,44 +14,68 @@ foreground {
                log.execline "fatal: ??"${1}"??: "${3}
 }
 
-# (why does `hoc -e` not work?)
-backtick -i -n Content-Length {
-       backtick -i -n message_length {
-               pipeline { s6-echo -n -- ${2} }
-               wc -c
-       }
-       importas -i -u message_length message_length
-
-       pipeline { s6-echo -- ${message_length}"*2 + 288" }
-       hoc
-}
-
 backtick -i -n Date { date -u "+%a, %d %b %Y %T GMT" }
-
-backtick -i -n extra_headers { cat configuration/default_headers/default }
+backtick -i -n extra_headers { http-get-extra-headers.execline ${1} }
 
 multisubstitute {
-# TODO:        importas -i -u Content-Length Content-Length
        importas -i -u Date Date
        importas -i -u extra_headers extra_headers
-       importas -D "invalid default hostname which should not match any hostname directory" hostname http_header_parse_Host
+       importas -D "?? no hostname ??" hostname http_header_parse_Host
 }
 
 if {
-       s6-echo -n -- "HTTP/1.1 "${1}" "${2}"\r
-Content-Type: application/xhtml+xml; charset=utf-8\r
+       # if there is an error response page for this status code:
+       ifelse {
+               s6-test -d configuration/error_response_pages/${hostname}/${1}
+                       -a -r configuration/error_response_pages/${hostname}/${1}
+       }
+       {
+               cd configuration/error_response_pages/${hostname}/${1}
+
+               backtick -D "application/xhtml+xml; charset=utf-8" -n Content-Type { cat Content-Type }
+               backtick -i -n Content-Length { wc -c message_body }
+
+               multisubstitute {
+                       importas -i -u Content-Type Content-Type
+                       importas -i -u Content-Length Content-Length
+               }
+
+               if {
+                       s6-echo -n -- "HTTP/1.1 "${1}" "${2}"\r
+Content-Type: "${Content-Type}"\r
+Content-Length: "${Content-Length}"\r
 Date: "${Date}"\r
 "${extra_headers}"\r
 \r
 "
-}
-
-if {
-       ifelse { s6-test -r configuration/error_response_pages/${hostname}/${1} }
-       {
-               # TODO: support `Content-Types`?? and `Content-Length`
-               cat configuration/error_response_pages/${hostname}/${1}
+               }
+               
+               cat message_body
        }
+               # default: no error status page on file; use a hardcoded default
+
+               # (why does `hoc -e` not work?)
+               backtick -i -n Content-Length {
+                       backtick -i -n message_length {
+                               pipeline { s6-echo -n -- ${2} }
+                               wc -c
+                       }
+                       importas -i -u message_length message_length
+
+                       pipeline { s6-echo -- ${message_length}"*2 + 288" }
+                       hoc
+               }
+               importas -i -u Content-Length Content-Length
+
+               if {
+                       s6-echo -n -- "HTTP/1.1 "${1}" "${2}"\r
+Content-Type: application/xhtml+xml; charset=utf-8\r
+Content-Length: "${Content-Length}"\r
+Date: "${Date}"\r
+"${extra_headers}"\r
+\r
+"
+               }
                s6-echo -n -- "<!DOCTYPE html>
 <html xmlns=\"http://www.w3.org/1999/xhtml\" lang=\"en\" xml:lang=\"en\">
 <head>
@@ -70,6 +94,6 @@ if {
 </html>
 "
 }
+
 # hack: write(3p) is unsafe
-#
 s6-sleep -m 512
diff --git a/visible-to-httpd/binaries/http-get-extra-headers.execline b/visible-to-httpd/binaries/http-get-extra-headers.execline
new file mode 100755 (executable)
index 0000000..39cd3c2
--- /dev/null
@@ -0,0 +1,87 @@
+#!/binaries/execlineb -WS0
+#
+# http-get-particular-headers.execline [status-code]
+#
+# sufficiently annoyingly complex resource-specific HTTP header logic that
+# gets reused a lot
+#
+# headers are specified in a header directory, which has a file for each
+# header you wish to send; this imposes structure with almost no parsing at all
+#
+# exploiting the filesystem as more or less a map (as opposed to the trivial
+# implementation: using a single file containing the desired headers) means the
+# user need not bother with editing files containing `\r\n`s
+# (however, it is almost certainly considerably more annoying to use)
+#
+# TODO: ? status code overrides support??
+# TODO: write a GUI?? with like, `yad(1)` or something??? idk
+
+multisubstitute {
+       importas -i hostname http_header_parse_Host
+       importas -i resource resource
+}
+
+foreground { log.execline "resource: "${resource} }
+
+backtick -n header-directory {
+       # for status code pages specifically
+       ifelse {
+               s6-test \${#} != 0
+                       -a -d configuration/error_response_pages/${1}/headers
+                       -a -r configuration/error_response_pages/${1}/headers
+       }
+       {
+               s6-echo -n -- configuration/error_response_pages/${1}/headers
+       }
+
+       # otherwise: prioritize header specifications in order of specificity:
+       # by resource, then by hostname, then the fallback (and finally nothing)
+       ifelse {
+               s6-test -d configuration/overrides/${resource}/headers
+                       -a -r configuration/overrides/${resource}/headers
+       }
+       {
+               s6-echo -n -- configuration/overrides/${resource}/headers
+       }
+       ifelse {
+               s6-test -d configuration/default_headers/${hostname}
+                       -a -r configuration/default_headers/${hostname}
+       }
+       {
+               s6-echo -n -- configuration/default_headers/${hostname}
+       }
+       # the preferred name for a DNS lookup should begin with an alphanumeric,
+       # so “-fallback”, since it begins with a hyphen, should never conflict
+       # with a hostname anybody would ever actually use
+       ifelse {
+               s6-test -d configuration/default_headers/-fallback
+                       -a -r configuration/default_headers/-fallback
+       }
+       {
+               s6-echo -n -- configuration/default_headers/-fallback
+       }
+               exit 1
+}
+
+# (we output nothing if there is no applicable header directory, which is fine)
+if -t { s6-test -v header-directory }
+       importas -i -u header-directory header-directory
+
+       foreground { log.execline "header-directory: "${header-directory} }
+
+       cd ${header-directory}
+       elglob -0 -s header_names *
+
+       # we’ll strip out `\r`s and `\n`s from filenames and file contents, in
+       # case the configuration should ever be made in a mischevious way
+       forx header_name { ${header_names} }
+               importas -i -u header_name header_name
+               if {
+                       pipeline { s6-echo -n -- ${header_name}": " }
+                       tr -d "\r\n"
+               }
+               if {
+                       pipeline { cat ${header_name} }
+                       tr -d "\r\n"
+               }
+       # do make sure not to forget to supply the final newline
index 823dc430e17372adc939f1ba77d9290736508c83..187f67be029a9e0f31420491b85d72c6b1583f61 100755 (executable)
@@ -216,13 +216,7 @@ if -X -n -t {
        # Security Policy; for the latter, consider HTTP 301 redirects
        #
        # be warned!! we do not validate these overrides!
-       backtick -i -n extra_headers {
-               ifelse { s6-test -r configuration/default_headers/override/${resource} }
-               {
-                       cat configuration/default_headers/override/${resource}
-               }
-                       cat configuration/default_headers/default
-       }
+       backtick -i -n extra_headers { http-get-extra-headers.execline }
 
        backtick -D "200 ok" -n status_code_and_message {
                if { s6-test -r configuration/overrides/${resource}/status_code }