···1515governor = "0.10.1"
1616http-body-util = "0.1.3"
1717log = "0.4.28"
1818-poem = { version = "3.1.12", features = ["compression"] }
1818+poem = { version = "3.1.12", features = ["acme", "compression"] }
1919reqwest = { version = "0.12.23", features = ["stream", "json"] }
2020reqwest-middleware = "0.4.2"
2121reqwest-retry = "0.7.0"
2222+rustls = "0.23.32"
2223serde = "1.0.219"
2324serde_json = { version = "1.0.143", features = ["raw_value"] }
2425thiserror = "2.0.16"
+37-4
src/bin/allegedly.rs
···11use allegedly::{
22- Db, Dt, ExportPage, FolderSource, HttpSource, PageBoundaryState, backfill, backfill_to_pg,
33- bin_init, pages_to_pg, pages_to_weeks, poll_upstream, serve,
22+ Db, Dt, ExportPage, FolderSource, HttpSource, ListenConf, PageBoundaryState, backfill,
33+ backfill_to_pg, bin_init, pages_to_pg, pages_to_weeks, poll_upstream, serve,
44};
55use clap::{CommandFactory, Parser, Subcommand};
66use reqwest::Url;
···1010#[derive(Debug, Parser)]
1111struct Cli {
1212 /// Upstream PLC server
1313- #[arg(short, long, env = "ALLEGEDLY_UPSTREAM")]
1313+ #[arg(short, long, global = true, env = "ALLEGEDLY_UPSTREAM")]
1414 #[clap(default_value = "https://plc.directory")]
1515 upstream: Url,
1616 #[command(subcommand)]
···8383 #[arg(short, long, env = "ALLEGEDLY_BIND")]
8484 #[clap(default_value = "127.0.0.1:8000")]
8585 bind: SocketAddr,
8686+ /// obtain a certificate from letsencrypt
8787+ ///
8888+ /// for now this will force listening on all interfaces at :80 and :443
8989+ /// (:80 will serve an "https required" error, *will not* redirect)
9090+ #[arg(
9191+ long,
9292+ conflicts_with("bind"),
9393+ requires("acme_cache_path"),
9494+ env = "ALLEGEDLY_ACME_DOMAIN"
9595+ )]
9696+ acme_domain: Vec<String>,
9797+ /// which local directory to keep the letsencrypt certs in
9898+ #[arg(long, requires("acme_domain"), env = "ALLEGEDLY_ACME_CACHE_PATH")]
9999+ acme_cache_path: Option<PathBuf>,
100100+ /// which public acme directory to use
101101+ ///
102102+ /// eg. letsencrypt staging: "https://acme-staging-v02.api.letsencrypt.org/directory"
103103+ #[arg(long, requires("acme_domain"), env = "ALLEGEDLY_ACME_DIRECTORY_URL")]
104104+ #[clap(default_value = "https://acme-v02.api.letsencrypt.org/directory")]
105105+ acme_directory_url: Url,
86106 },
87107 /// Poll an upstream PLC server and log new ops to stdout
88108 Tail {
···224244 wrap,
225245 wrap_pg,
226246 bind,
247247+ acme_domain,
248248+ acme_cache_path,
249249+ acme_directory_url,
227250 } => {
228251 let db = Db::new(wrap_pg.as_str()).await.unwrap();
229252 let latest = db
···249272 pages_to_pg(poll_db, rx).await.unwrap();
250273 });
251274252252- serve(&args.upstream, wrap, bind).await.unwrap();
275275+ let listen_conf = match (bind, acme_domain.is_empty(), acme_cache_path) {
276276+ (_, false, Some(cache_path)) => ListenConf::Acme {
277277+ domains: acme_domain,
278278+ cache_path,
279279+ directory_url: acme_directory_url.to_string(),
280280+ },
281281+ (bind, true, None) => ListenConf::Bind(bind),
282282+ (_, _, _) => unreachable!(),
283283+ };
284284+285285+ serve(&args.upstream, wrap, listen_conf).await.unwrap();
253286 }
254287 Commands::Tail { after } => {
255288 let mut url = args.upstream;
+1-1
src/lib.rs
···10101111pub use backfill::backfill;
1212pub use client::{CLIENT, UA};
1313-pub use mirror::serve;
1313+pub use mirror::{ListenConf, serve};
1414pub use plc_pg::{Db, backfill_to_pg, pages_to_pg};
1515pub use poll::{PageBoundaryState, get_page, poll_upstream};
1616pub use ratelimit::GovernorMiddleware;