cista-storage/cista/serve.py

62 lines
1.9 KiB
Python
Raw Normal View History

import os
import re
from pathlib import Path, PurePath
from sanic import Sanic
from cista import config, server80
def run(dev=False):
"""Run Sanic main process that spawns worker processes to serve HTTP requests."""
from .app import app
url, opts = parse_listen(config.config.listen)
# Silence Sanic's warning about running in production rather than debug
os.environ["SANIC_IGNORE_PRODUCTION_WARNING"] = "1"
confdir = config.conffile.parent
wwwroot = PurePath(__file__).parent / "wwwroot"
if opts.get("ssl"):
# Run plain HTTP redirect/acme server on port 80
2023-10-21 17:17:09 +01:00
server80.app.prepare(port=80, motd=False)
domain = opts["host"]
check_cert(confdir / domain, domain)
opts["ssl"] = str(confdir / domain) # type: ignore
app.prepare(
**opts,
motd=False,
dev=dev,
auto_reload=dev,
reload_dir={confdir, wwwroot},
access_log=True,
) # type: ignore
Sanic.serve()
def check_cert(certdir, domain):
if (certdir / "privkey.pem").exist() and (certdir / "fullchain.pem").exists():
return
# TODO: Use certbot to fetch a cert
raise ValueError(
f"TLS certificate files privkey.pem and fullchain.pem needed in {certdir}"
)
def parse_listen(listen):
if listen.startswith("/"):
unix = Path(listen).resolve()
if not unix.parent.exists():
raise ValueError(
f"Directory for unix socket does not exist: {unix.parent}/"
)
return "http://localhost", {"unix": unix}
elif re.fullmatch(r"(\w+(-\w+)*\.)+\w{2,}", listen, re.UNICODE):
return f"https://{listen}", {"host": listen, "port": 443, "ssl": True}
else:
try:
addr, _port = listen.split(":", 1)
port = int(_port)
except Exception:
raise ValueError(f"Invalid listen address: {listen}")
return f"http://localhost:{port}", {"host": addr, "port": port}