diff options
| author | Igor Soarez <igor@soarez.org> | 2026-10-13 14:52:43 +0100 |
|---|---|---|
| committer | Igor Soarez <igor@soarez.org> | 2026-10-13 14:52:43 +0100 |
| commit | c0771c839df57a627ceb21bd398752ba2b1ed3f1 (patch) | |
| tree | bb20090521846168732ab87af1dadcd897cc3f42 /bin | |
| parent | 20b4e6a4f89776d1d0250d95cce341aa77d03da2 (diff) | |
dot-request: --inbox, and xz compression past 400 KB
--inbox files into another inbox than dot: the path it posts to and the
namespace it signs in both follow it, so the key signs for that inbox only.
DOT_REQUEST_URL still overrides the whole URL for testing.
A signed request over 400 KB -- the inbox's limit on the wire -- now goes
xz -9e compressed with Content-Encoding: xz, which the inbox undoes before
checking anything; a smaller one goes as it is. --compress and --no-compress
override that either way. Compressing needs xz, so it joins the Brewfile;
without it a request that must be compressed is refused, never sent plain.
Checked against a local inbox: 148 KB sent plain, 740 KB compressed to 37 KB
and accepted, --no-compress over the limit refused with 413, --compress on a
small request accepted, a bad --inbox name refused before signing.
Diffstat (limited to 'bin')
| -rwxr-xr-x | bin/dot-request | 52 |
1 files changed, 47 insertions, 5 deletions
diff --git a/bin/dot-request b/bin/dot-request index c68418e..8dcb17f 100755 --- a/bin/dot-request +++ b/bin/dot-request @@ -19,15 +19,27 @@ # key authorised for that inbox. Set DOT_REQUEST_URL to point somewhere else # when testing. # +# --inbox NAME file into another inbox than dot. The key must be +# authorised there too, and signs for that inbox only. +# --compress send it xz-compressed (xz -9e), whatever its size +# --no-compress send it as it is, whatever its size +# +# By default a signed request over 400 KB goes xz-compressed and a smaller one +# as it is: the inbox takes 400 KB on the wire, and more than that only +# compressed, up to what the inbox allows once decompressed. Compressing needs +# xz; without it, a request that must be compressed is refused, not sent plain. +# # Runs under macOS's /bin/bash 3.2. set -euo pipefail key="" -url="${DOT_REQUEST_URL:-https://req.soarez.net/inbox/dot}" +inbox="dot" +compress="" # empty: decided by size +compress_over=$((400 * 1024)) usage() { - sed -n '3,25p' "$0" | sed 's/^# \{0,1\}//' + sed -n '3,32p' "$0" | sed 's/^# \{0,1\}//' exit "${1:-0}" } @@ -35,11 +47,23 @@ while [[ $# -gt 0 ]]; do case "$1" in --key) key="${2:-}"; shift 2 ;; --key=*) key="${1#--key=}"; shift ;; + --inbox) inbox="${2:-}"; shift 2 ;; + --inbox=*) inbox="${1#--inbox=}"; shift ;; + --compress) compress=yes; shift ;; + --no-compress) compress=no; shift ;; -h|--help) usage 0 ;; *) >&2 echo "dot-request: unknown argument: $1"; usage 1 ;; esac done +# The inbox is a path segment there and a signature namespace here: held to +# the same names the inbox itself accepts. +if [[ ! "${inbox}" =~ ^[A-Za-z0-9_-]{1,32}$ ]]; then + >&2 echo "dot-request: --inbox: '${inbox}' is not an inbox name" + exit 1 +fi +url="${DOT_REQUEST_URL:-https://req.soarez.net/inbox/${inbox}}" + if [[ -z "${key}" ]]; then >&2 echo "dot-request: --key is required (the ssh key this machine signs with)" exit 1 @@ -70,12 +94,30 @@ fi # against the same one. It is what stops a request signed here being replayed # into a different inbox, and what stops this key being made to sign for # anything else. -ssh-keygen -Y sign -q -f "${key}" -n sz-request:dot "${tmp}/request.md" +ssh-keygen -Y sign -q -f "${key}" -n "sz-request:${inbox}" "${tmp}/request.md" cat "${tmp}/request.md" "${tmp}/request.md.sig" > "${tmp}/signed.md" +# What is signed is the text; compression is only how it travels, undone by +# the inbox before it checks anything. +size="$(wc -c < "${tmp}/signed.md" | tr -d ' ')" +if [[ -z "${compress}" ]]; then + if [[ "${size}" -gt "${compress_over}" ]]; then compress=yes; else compress=no; fi +fi +encoding=() +body="${tmp}/signed.md" +if [[ "${compress}" == yes ]]; then + if ! command -v xz >/dev/null; then + >&2 echo "dot-request: ${size} bytes needs compressing, and there is no xz here" + exit 1 + fi + xz -9e -c "${tmp}/signed.md" > "${tmp}/signed.md.xz" + body="${tmp}/signed.md.xz" + encoding=(-H 'Content-Encoding: xz') +fi + code="$(curl -sS -o "${tmp}/reply" -w '%{http_code}' \ - -X POST -H 'Content-Type: text/markdown' \ - --data-binary "@${tmp}/signed.md" "${url}")" + -X POST -H 'Content-Type: text/markdown' ${encoding[@]+"${encoding[@]}"} \ + --data-binary "@${body}" "${url}")" if [[ "${code}" == "201" ]]; then echo "submitted: $(cat "${tmp}/reply")" |
