# Caddy in front of veiled-server.
#
# Caddy gets a certificate on its own and passes the WebSocket upgrade without any
# extra directives, so this file is short. The one detail that is not obvious is the
# upstream: veiled-server speaks TLS on its control port (docs/protocol.md section 1),
# so the proxy has to connect with TLS and skip verification of the server's self-signed
# certificate. Verification of that hop is the job of the certificate on the public
# name, not of a second certificate nobody sees.
#
# As with the nginx sample: media is UDP 8444 and cannot come through here. Browser
# clients carry media over the WebSocket instead, which does come through here.

{
	# Where Let's Encrypt sends expiry notices.
	email admin@example.org
}

chat.example.org {
	# Ciphertext, key wrappers and the web client. Compression helps the text paths
	# and costs nothing on media, which is already incompressible.
	encode zstd gzip

	# Message bodies are capped at 8 KB of ciphertext and there are no uploads in this
	# version. Keep a small ceiling.
	request_body {
		max_size 1MB
	}

	reverse_proxy https://127.0.0.1:8443 {
		transport http {
			# The upstream certificate is the server's own, replaced by a real one
			# when the host installs it. Change tls_insecure_skip_verify to tls_trusted_ca_certs
			# with the server's CA if you want this hop verified too.
			tls
			tls_insecure_skip_verify
		}
		header_up X-Real-IP {remote_host}
		# Long-lived sockets: a quiet channel must not be closed by a timeout.
		flush_interval -1
	}

	header {
		Strict-Transport-Security "max-age=31536000"
		X-Content-Type-Options "nosniff"
		Referrer-Policy "no-referrer"
		-Server
	}

	log {
		output file /var/log/caddy/veiled.log {
			roll_size 20mb
			roll_keep 5
		}
	}
}

# Alternative, if you terminate TLS only here and run the server as
# `veiled-server run --insecure` on a loopback address. Do not combine --insecure with a
# public bind.
#
# chat.example.org {
# 	reverse_proxy 127.0.0.1:8443
# }
