4d9755a177d6b6660e589ec9f322e3b932fdb391
braney
Sun Aug 23 15:13:54 2026 -0700
ts: scope the CORS header to the data directories, refs #37867
The per-ticket httpd.conf set Access-Control-Allow-Origin to * at server scope,
which covered CGI responses too. The live /usr/local/apache/conf/httpd.conf
sets that header on htdocs and on the trash directories only, never server-wide
and never on cgi-bin. A parked instance has no password, so a wildcard on the
CGI output let any page in the developer's browser read it through the open ssh
tunnel.
The header now sits in the htdocs and trash Directory blocks, with the
Access-Control-Allow-Headers: Range line that accompanies it in the live config,
so range requests on trash files behave the same as in production.
Also replace a tab or newline in the free-text note with a space before it is
written to ports.tsv. The registry is one tab-separated line per ticket, so
those characters appended a malformed row instead of reading back as the note.
Instances parked before this change need ts sync to pick up the new config.
diff --git src/utils/ts/ts src/utils/ts/ts
index 02c9bd36f60..fce5fd87b04 100755
--- src/utils/ts/ts
+++ src/utils/ts/ts
@@ -171,45 +171,51 @@
LoadModule cgi_module $MODDIR/mod_cgi.so
LoadModule log_config_module $MODDIR/mod_log_config.so
TypesConfig /etc/mime.types
DirectoryIndex index.html
PidFile "$dir/httpd.pid"
ErrorLog "$dir/logs/error_log"
LogFormat "%h %l %u %t \"%r\" %>s %b" common
CustomLog "$dir/logs/access_log" common
DocumentRoot "$dir/$HTDOCS_NAME"
ScriptAlias /cgi-bin/ "$dir/cgi-bin/"
Alias /trash/ "$SHARED_TRASH/"
-Header set Access-Control-Allow-Origin "*"
-
+# CORS is scoped to the data directories only, matching the live
+# /usr/local/apache/conf/httpd.conf, which sets it on htdocs and trash and never
+# on cgi-bin. A parked instance has no password, so a server-wide wildcard would
+# let any page in the developer's browser read CGI output through the open tunnel.
AllowOverride None
Options +ExecCGI +FollowSymLinks
Require all granted
AllowOverride None
Options +FollowSymLinks +Includes
+ Header set Access-Control-Allow-Origin "*"
+ Header set Access-Control-Allow-Headers: Range
Require all granted
AllowOverride None
Options +FollowSymLinks
+ Header set Access-Control-Allow-Origin "*"
+ Header set Access-Control-Allow-Headers: Range
Require all granted
EOF
}
# --- lifecycle ---------------------------------------------------------------
startHttpd() {
local tkt="$1" dir; dir="$(tsDir "$1")"
[[ -f "$dir/httpd.conf" ]] || die "no httpd.conf for RM $tkt (create it first)"
if [[ -n "$(pidOf "$tkt")" ]]; then
echo "RM $tkt httpd already running (pid $(pidOf "$tkt"))."; return 0
fi
"$HTTPD" -f "$dir/httpd.conf" -t >/dev/null # syntax check first
"$HTTPD" -f "$dir/httpd.conf"
sleep 1
@@ -219,30 +225,33 @@
}
stopHttpd() {
local tkt="$1" dir; dir="$(tsDir "$1")"
local pid; pid="$(pidOf "$tkt")"
if [[ -z "$pid" ]]; then echo "RM $tkt httpd not running."; return 0; fi
kill "$pid" 2>/dev/null || true
sleep 1
[[ -z "$(pidOf "$tkt")" ]] && echo "RM $tkt httpd stopped." || die "RM $tkt httpd did not stop (pid $pid)"
}
# --- subcommands -------------------------------------------------------------
cmd_create() {
local tkt="$1"; shift || true
local note="${*:-}"
+ # the registry is one tab-separated line per ticket, so a tab or newline in the
+ # free-text note would append a malformed row instead of reading back as the note
+ note="$(printf '%s' "$note" | tr '\t\n\r' ' ')"
validTkt "$tkt"
[[ -d "$LIVE_CGI" ]] || die "no live sandbox at $LIVE_CGI"
[[ -d "$LIVE_HTDOCS" ]] || die "no live htdocs at $LIVE_HTDOCS"
mkdir -p "$ROOT"
[[ -z "$(regPort "$tkt")" ]] || die "RM $tkt already exists (port $(regPort "$tkt")); use sync/remove"
local port; port="$(nextPort)"
freeze "$tkt"
writeConf "$tkt" "$port"
printf '%s\t%s\t%s\t%s\n' "$tkt" "$port" "$(date +%Y-%m-%d)" "$note" >> "$REG"
startHttpd "$tkt"
echo
echo "RM $tkt parked on 127.0.0.1:$port"
echo " on hgwdev: curl 'http://127.0.0.1:$port/cgi-bin/hgTracks?db=hg38'"
echo " you, remote: ts tunnel $tkt -> http://localhost:$port/cgi-bin/hgTracks"
echo " a colleague: ssh -N -L $port:localhost:$port @$HGWDEV -> http://localhost:$port/cgi-bin/hgTracks"