Adds first-class HTTP-01 challenge serving, so CertMate can issue certificates over HTTP-01 (not just DNS-01) when reached at /.well-known/acme-challenge/.
What's new
- A public Flask route serves the challenge tokens certbot writes during HTTP-01 validation (unauthenticated, as the ACME server fetches it anonymously;
send_from_directory/werkzeug.safe_joinblocks path traversal). - A single
acme_webroot_dir()resolver is the source of truth for the three call sites that must agree — certbot's--webrootargument, the challenge-directory pre-creation, and the serving route — so the write and serve paths cannot drift. Override the location with theACME_CHALLENGES_DIRenvironment variable (default<cwd>/data/acme-challenges, unchanged).
Originally contributed by @rob-infoglobe (#253); finished with the shared-resolver fix and tests (#262).
Verification
New unit suite (tests/test_acme_challenge_serving.py, 5 cases incl. the write/serve anti-drift guard). Full E2E gate green: Docker smoke + CSP/auth/settings/pages/backup + real Let's Encrypt issuance and renewal over Cloudflare DNS-01 (90/90).