quic-go v0.59.0 (shipped with Caddy v2.11.2) removed quic.Connection as a public interface and quic-go/logging as a public package, breaking H3App's connection-wrapping approach. Resolution: - Remove H3App (h3app.go) entirely; Caddy handles h3 natively when h3 is in the protocols list. - Rewrite h3conn.go to keep only tryParseH3ControlStream + varint/name utilities (tested, useful for future stream-level tapping if the API ever re-exposes it). - FPHandler.ServeHTTP: for h3 requests, type-assert ResponseWriter to http3.Settingser (the public interface exposed by quic-go/http3 v0.59), read the peer's Settings after ReceivedSettings channel closes, emit h3_settings fp record. - https/entrypoint.sh: include h3 in CADDY_PROTOCOLS (Caddy now owns UDP/443); remove DECNET_H3_GLOBAL block. - Update go.mod/go.sum to caddy v2.11.2 + quic-go v0.59.0. - Update test_https_compose_h3_app.py to expect h3 in protocols when http/3 is selected, and assert decnet_h3 block is absent. - All Go tests (9) and Python tests (15) remain green.
89 lines
2.2 KiB
Bash
89 lines
2.2 KiB
Bash
#!/bin/bash
|
|
set -e
|
|
|
|
TLS_DIR="/opt/tls"
|
|
mkdir -p "$TLS_DIR"
|
|
|
|
# TLS_CERT/TLS_KEY may arrive as either a host-side path OR raw PEM content.
|
|
# Detect by looking for a PEM header; if present, write to disk.
|
|
if [ -n "$TLS_CERT" ] && printf '%s' "$TLS_CERT" | grep -q 'BEGIN '; then
|
|
printf '%s' "$TLS_CERT" > "$TLS_DIR/cert.pem"
|
|
CERT="$TLS_DIR/cert.pem"
|
|
else
|
|
CERT="${TLS_CERT:-$TLS_DIR/cert.pem}"
|
|
fi
|
|
if [ -n "$TLS_KEY" ] && printf '%s' "$TLS_KEY" | grep -q 'BEGIN '; then
|
|
printf '%s' "$TLS_KEY" > "$TLS_DIR/key.pem"
|
|
chmod 600 "$TLS_DIR/key.pem"
|
|
KEY="$TLS_DIR/key.pem"
|
|
else
|
|
KEY="${TLS_KEY:-$TLS_DIR/key.pem}"
|
|
fi
|
|
|
|
# Generate a self-signed certificate if none exists
|
|
if [ ! -f "$CERT" ] || [ ! -f "$KEY" ]; then
|
|
CN="${TLS_CN:-${NODE_NAME:-localhost}}"
|
|
openssl req -x509 -newkey rsa:2048 -nodes \
|
|
-keyout "$KEY" -out "$CERT" \
|
|
-days 3650 -subj "/CN=$CN" \
|
|
2>/dev/null
|
|
fi
|
|
|
|
# Parse HTTP_VERSIONS JSON → Caddy protocol tokens.
|
|
# Caddy handles h3 natively; h3 SETTINGS are captured via FPHandler (http3.Settingser).
|
|
CADDY_PROTOCOLS=$(python3 -c "
|
|
import json, os
|
|
versions = json.loads(os.environ.get('HTTP_VERSIONS', '[\"http/1.1\"]'))
|
|
tokens = []
|
|
if 'http/1.1' in versions:
|
|
tokens.append('h1')
|
|
if 'http/2' in versions:
|
|
tokens.append('h2')
|
|
if 'http/3' in versions:
|
|
tokens.append('h3')
|
|
print(' '.join(tokens) if tokens else 'h1')
|
|
")
|
|
|
|
DECNET_FP_SOCK="${DECNET_FP_SOCK:-/run/decnet/fp.sock}"
|
|
# Remove stale socket from a previous run
|
|
rm -f "$DECNET_FP_SOCK"
|
|
|
|
cat > /etc/caddy/Caddyfile <<EOF
|
|
{
|
|
admin off
|
|
servers :443 {
|
|
protocols ${CADDY_PROTOCOLS}
|
|
listener_wrappers {
|
|
decnet_fp
|
|
}
|
|
}
|
|
}
|
|
|
|
:443 {
|
|
tls ${CERT} ${KEY}
|
|
route {
|
|
decnet_fp
|
|
reverse_proxy 127.0.0.1:8443
|
|
}
|
|
}
|
|
EOF
|
|
|
|
python3 /opt/server.py &
|
|
FLASK_PID=$!
|
|
|
|
# Wait for Flask to be ready before handing off to Caddy
|
|
python3 -c "
|
|
import socket, sys, time
|
|
for _ in range(80):
|
|
try:
|
|
s = socket.create_connection(('127.0.0.1', 8443), timeout=0.25)
|
|
s.close()
|
|
sys.exit(0)
|
|
except OSError:
|
|
time.sleep(0.1)
|
|
print('Flask did not bind to :8443 in time', file=sys.stderr)
|
|
sys.exit(1)
|
|
" || { echo 'Flask startup failed — aborting'; kill $FLASK_PID 2>/dev/null; exit 1; }
|
|
|
|
exec caddy run --config /etc/caddy/Caddyfile
|