summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Soarez <igor@soarez.org>2026-10-13 14:52:43 +0100
committerIgor Soarez <igor@soarez.org>2026-10-13 14:52:43 +0100
commitc0771c839df57a627ceb21bd398752ba2b1ed3f1 (patch)
treebb20090521846168732ab87af1dadcd897cc3f42
parent20b4e6a4f89776d1d0250d95cce341aa77d03da2 (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.
-rw-r--r--Brewfile1
-rwxr-xr-xbin/dot-request52
2 files changed, 48 insertions, 5 deletions
diff --git a/Brewfile b/Brewfile
index 6f3f465..bbf4f2a 100644
--- a/Brewfile
+++ b/Brewfile
@@ -26,6 +26,7 @@ brew "gh" # config/profile hands it the GitHub token
brew "mosh" # alacritty-mosh, mosh-tmux.sh
brew "terminal-notifier" # bin/notify
brew "fswatch" # bin/sz-wait-for
+brew "xz" # bin/dot-request, for requests over 400 KB
brew "n" # node versions, under $N_PREFIX
brew "bash-completion"
brew "shellcheck"
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")"