Constellation, Spacedust, Slingshot, UFOs: atproto crates and services for microcosm

acme????

Changed files
+222 -11
slingshot
+189
Cargo.lock
··· 181 181 ] 182 182 183 183 [[package]] 184 + name = "asn1-rs" 185 + version = "0.7.1" 186 + source = "registry+https://github.com/rust-lang/crates.io-index" 187 + checksum = "56624a96882bb8c26d61312ae18cb45868e5a9992ea73c58e45c3101e56a1e60" 188 + dependencies = [ 189 + "asn1-rs-derive", 190 + "asn1-rs-impl", 191 + "displaydoc", 192 + "nom", 193 + "num-traits", 194 + "rusticata-macros", 195 + "thiserror 2.0.12", 196 + "time", 197 + ] 198 + 199 + [[package]] 200 + name = "asn1-rs-derive" 201 + version = "0.6.0" 202 + source = "registry+https://github.com/rust-lang/crates.io-index" 203 + checksum = "3109e49b1e4909e9db6515a30c633684d68cdeaa252f215214cb4fa1a5bfee2c" 204 + dependencies = [ 205 + "proc-macro2", 206 + "quote", 207 + "syn 2.0.103", 208 + "synstructure", 209 + ] 210 + 211 + [[package]] 212 + name = "asn1-rs-impl" 213 + version = "0.2.0" 214 + source = "registry+https://github.com/rust-lang/crates.io-index" 215 + checksum = "7b18050c2cd6fe86c3a76584ef5e0baf286d038cda203eb6223df2cc413565f7" 216 + dependencies = [ 217 + "proc-macro2", 218 + "quote", 219 + "syn 2.0.103", 220 + ] 221 + 222 + [[package]] 184 223 name = "async-channel" 185 224 version = "2.5.0" 186 225 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1202 1241 ] 1203 1242 1204 1243 [[package]] 1244 + name = "der-parser" 1245 + version = "10.0.0" 1246 + source = "registry+https://github.com/rust-lang/crates.io-index" 1247 + checksum = "07da5016415d5a3c4dd39b11ed26f915f52fc4e0dc197d87908bc916e51bc1a6" 1248 + dependencies = [ 1249 + "asn1-rs", 1250 + "displaydoc", 1251 + "nom", 1252 + "num-bigint", 1253 + "num-traits", 1254 + "rusticata-macros", 1255 + ] 1256 + 1257 + [[package]] 1205 1258 name = "deranged" 1206 1259 version = "0.4.0" 1207 1260 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 1906 1959 checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4" 1907 1960 dependencies = [ 1908 1961 "cfg-if", 1962 + "js-sys", 1909 1963 "libc", 1910 1964 "r-efi", 1911 1965 "wasi 0.14.2+wasi-0.2.4", 1966 + "wasm-bindgen", 1912 1967 ] 1913 1968 1914 1969 [[package]] ··· 2869 2924 ] 2870 2925 2871 2926 [[package]] 2927 + name = "lru-slab" 2928 + version = "0.1.2" 2929 + source = "registry+https://github.com/rust-lang/crates.io-index" 2930 + checksum = "112b39cec0b298b6c1999fee3e31427f74f676e4cb9879ed1a121b43661a4154" 2931 + 2932 + [[package]] 2872 2933 name = "lsm-tree" 2873 2934 version = "2.8.0" 2874 2935 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3406 3467 ] 3407 3468 3408 3469 [[package]] 3470 + name = "oid-registry" 3471 + version = "0.8.1" 3472 + source = "registry+https://github.com/rust-lang/crates.io-index" 3473 + checksum = "12f40cff3dde1b6087cc5d5f5d4d65712f34016a03ed60e9c08dcc392736b5b7" 3474 + dependencies = [ 3475 + "asn1-rs", 3476 + ] 3477 + 3478 + [[package]] 3409 3479 name = "once_cell" 3410 3480 version = "1.21.3" 3411 3481 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 3710 3780 source = "registry+https://github.com/rust-lang/crates.io-index" 3711 3781 checksum = "9f977080932c87287147dca052951c3e2696f8759863f6b4e4c0c9ffe7a4cc8b" 3712 3782 dependencies = [ 3783 + "base64 0.22.1", 3713 3784 "bytes", 3785 + "chrono", 3714 3786 "futures-util", 3715 3787 "headers", 3716 3788 "http", ··· 3725 3797 "pin-project-lite", 3726 3798 "poem-derive", 3727 3799 "quick-xml", 3800 + "rcgen", 3728 3801 "regex", 3802 + "reqwest", 3729 3803 "rfc7239", 3804 + "ring", 3805 + "rustls-pemfile", 3730 3806 "serde", 3731 3807 "serde_json", 3732 3808 "serde_urlencoded", ··· 3736 3812 "tempfile", 3737 3813 "thiserror 2.0.12", 3738 3814 "tokio", 3815 + "tokio-rustls 0.26.2", 3739 3816 "tokio-stream", 3740 3817 "tokio-util", 3741 3818 "tracing", 3742 3819 "wildmatch", 3820 + "x509-parser", 3743 3821 ] 3744 3822 3745 3823 [[package]] ··· 3923 4001 ] 3924 4002 3925 4003 [[package]] 4004 + name = "quinn" 4005 + version = "0.11.8" 4006 + source = "registry+https://github.com/rust-lang/crates.io-index" 4007 + checksum = "626214629cda6781b6dc1d316ba307189c85ba657213ce642d9c77670f8202c8" 4008 + dependencies = [ 4009 + "bytes", 4010 + "cfg_aliases", 4011 + "pin-project-lite", 4012 + "quinn-proto", 4013 + "quinn-udp", 4014 + "rustc-hash 2.1.1", 4015 + "rustls 0.23.28", 4016 + "socket2 0.5.9", 4017 + "thiserror 2.0.12", 4018 + "tokio", 4019 + "tracing", 4020 + "web-time", 4021 + ] 4022 + 4023 + [[package]] 4024 + name = "quinn-proto" 4025 + version = "0.11.12" 4026 + source = "registry+https://github.com/rust-lang/crates.io-index" 4027 + checksum = "49df843a9161c85bb8aae55f101bc0bac8bcafd637a620d9122fd7e0b2f7422e" 4028 + dependencies = [ 4029 + "bytes", 4030 + "getrandom 0.3.3", 4031 + "lru-slab", 4032 + "rand 0.9.1", 4033 + "ring", 4034 + "rustc-hash 2.1.1", 4035 + "rustls 0.23.28", 4036 + "rustls-pki-types", 4037 + "slab", 4038 + "thiserror 2.0.12", 4039 + "tinyvec", 4040 + "tracing", 4041 + "web-time", 4042 + ] 4043 + 4044 + [[package]] 4045 + name = "quinn-udp" 4046 + version = "0.5.13" 4047 + source = "registry+https://github.com/rust-lang/crates.io-index" 4048 + checksum = "fcebb1209ee276352ef14ff8732e24cc2b02bbac986cd74a4c81bcb2f9881970" 4049 + dependencies = [ 4050 + "cfg_aliases", 4051 + "libc", 4052 + "once_cell", 4053 + "socket2 0.5.9", 4054 + "tracing", 4055 + "windows-sys 0.52.0", 4056 + ] 4057 + 4058 + [[package]] 3926 4059 name = "quote" 3927 4060 version = "1.0.40" 3928 4061 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4035 4168 ] 4036 4169 4037 4170 [[package]] 4171 + name = "rcgen" 4172 + version = "0.12.1" 4173 + source = "registry+https://github.com/rust-lang/crates.io-index" 4174 + checksum = "48406db8ac1f3cbc7dcdb56ec355343817958a356ff430259bb07baf7607e1e1" 4175 + dependencies = [ 4176 + "pem", 4177 + "ring", 4178 + "time", 4179 + "yasna", 4180 + ] 4181 + 4182 + [[package]] 4038 4183 name = "redox_syscall" 4039 4184 version = "0.5.11" 4040 4185 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4144 4289 "native-tls", 4145 4290 "percent-encoding", 4146 4291 "pin-project-lite", 4292 + "quinn", 4293 + "rustls 0.23.28", 4294 + "rustls-native-certs", 4147 4295 "rustls-pki-types", 4148 4296 "serde", 4149 4297 "serde_json", ··· 4151 4299 "sync_wrapper", 4152 4300 "tokio", 4153 4301 "tokio-native-tls", 4302 + "tokio-rustls 0.26.2", 4154 4303 "tokio-util", 4155 4304 "tower", 4156 4305 "tower-http", ··· 4267 4416 ] 4268 4417 4269 4418 [[package]] 4419 + name = "rusticata-macros" 4420 + version = "4.1.0" 4421 + source = "registry+https://github.com/rust-lang/crates.io-index" 4422 + checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" 4423 + dependencies = [ 4424 + "nom", 4425 + ] 4426 + 4427 + [[package]] 4270 4428 name = "rustix" 4271 4429 version = "0.38.44" 4272 4430 source = "registry+https://github.com/rust-lang/crates.io-index" ··· 4313 4471 checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" 4314 4472 dependencies = [ 4315 4473 "aws-lc-rs", 4474 + "log", 4316 4475 "once_cell", 4476 + "ring", 4317 4477 "rustls-pki-types", 4318 4478 "rustls-webpki 0.103.3", 4319 4479 "subtle", ··· 4346 4506 version = "1.11.0" 4347 4507 source = "registry+https://github.com/rust-lang/crates.io-index" 4348 4508 checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" 4509 + dependencies = [ 4510 + "web-time", 4511 + ] 4349 4512 4350 4513 [[package]] 4351 4514 name = "rustls-webpki" ··· 6246 6409 ] 6247 6410 6248 6411 [[package]] 6412 + name = "x509-parser" 6413 + version = "0.17.0" 6414 + source = "registry+https://github.com/rust-lang/crates.io-index" 6415 + checksum = "4569f339c0c402346d4a75a9e39cf8dad310e287eef1ff56d4c68e5067f53460" 6416 + dependencies = [ 6417 + "asn1-rs", 6418 + "data-encoding", 6419 + "der-parser", 6420 + "lazy_static", 6421 + "nom", 6422 + "oid-registry", 6423 + "rusticata-macros", 6424 + "thiserror 2.0.12", 6425 + "time", 6426 + ] 6427 + 6428 + [[package]] 6249 6429 name = "xxhash-rust" 6250 6430 version = "0.8.15" 6251 6431 source = "registry+https://github.com/rust-lang/crates.io-index" 6252 6432 checksum = "fdd20c5420375476fbd4394763288da7eb0cc0b8c11deed431a91562af7335d3" 6433 + 6434 + [[package]] 6435 + name = "yasna" 6436 + version = "0.5.2" 6437 + source = "registry+https://github.com/rust-lang/crates.io-index" 6438 + checksum = "e17bb3549cc1321ae1296b9cdc2698e2b6cb1992adfa19a8c72e5b7a738f44cd" 6439 + dependencies = [ 6440 + "time", 6441 + ] 6253 6442 6254 6443 [[package]] 6255 6444 name = "yoke"
+1 -1
slingshot/Cargo.toml
··· 17 17 log = "0.4.27" 18 18 metrics = "0.24.2" 19 19 metrics-exporter-prometheus = { version = "0.17.1", features = ["http-listener"] } 20 - poem = "3.1.12" 20 + poem = { version = "3.1.12", features = ["acme"] } 21 21 poem-openapi = { version = "5.1.16", features = ["scalar"] } 22 22 reqwest = { version = "0.12.22", features = ["json"] } 23 23 serde = { version = "1.0.219", features = ["derive"] }
+3 -1
slingshot/src/error.rs
··· 14 14 15 15 #[derive(Debug, Error)] 16 16 pub enum ServerError { 17 + #[error("server build error: {0}")] 18 + AcmeBuildError(std::io::Error), 17 19 #[error("server exited: {0}")] 18 - ServerExited(String), 20 + ServerExited(std::io::Error), 19 21 } 20 22 21 23 #[derive(Debug, Error)]
+29 -9
slingshot/src/server.rs
··· 4 4 use std::sync::Arc; 5 5 use tokio_util::sync::CancellationToken; 6 6 7 - use poem::{Endpoint, Route, Server, endpoint::make_sync, listener::TcpListener}; 7 + use poem::{ 8 + Endpoint, Route, Server, 9 + endpoint::make_sync, 10 + listener::{ 11 + Listener, TcpListener, 12 + acme::{AutoCert, LETS_ENCRYPT_PRODUCTION}, 13 + }, 14 + }; 8 15 use poem_openapi::{ 9 16 ApiResponse, Object, OpenApi, OpenApiService, param::Query, payload::Json, types::Example, 10 17 }; ··· 211 218 /// 212 219 /// - PDS proxying offers a level of client IP anonymity from slingshot 213 220 /// - slingshot *may* implement more generous per-user rate-limits for proxied requests in the future 214 - fn get_did_doc(host: String) -> impl Endpoint { 221 + fn get_did_doc(host: &str) -> impl Endpoint + use<> { 215 222 let doc = poem::web::Json(AppViewDoc { 216 223 id: format!("did:web:{host}"), 217 224 service: [AppViewService { ··· 235 242 .server("http://localhost:3000") 236 243 .url_prefix("/xrpc"); 237 244 238 - let mut app = Route::new() 245 + let app = Route::new() 239 246 .nest("/", api_service.scalar()) 240 247 .nest("/openapi.json", api_service.spec_endpoint()) 241 248 .nest("/xrpc/", api_service); 242 249 243 250 if let Some(host) = host { 244 - app = app.at("/.well-known/did.json", get_did_doc(host)); 245 - }; 251 + let app = app.at("/.well-known/did.json", get_did_doc(&host)); 252 + 253 + let auto_cert = AutoCert::builder() 254 + .directory_url(LETS_ENCRYPT_PRODUCTION) 255 + .domain(&host) 256 + .build() 257 + .map_err(ServerError::AcmeBuildError)?; 246 258 247 - Server::new(TcpListener::bind("127.0.0.1:3000")) 248 - .run(app) 249 - .await 250 - .map_err(|e| ServerError::ServerExited(format!("uh oh: {e:?}"))) 259 + Server::new(TcpListener::bind("0.0.0.0:443").acme(auto_cert)) 260 + .name("slingshot") 261 + .run(app) 262 + .await 263 + .map_err(ServerError::ServerExited) 264 + } else { 265 + Server::new(TcpListener::bind("127.0.0.1:3000")) 266 + .name("slingshot") 267 + .run(app) 268 + .await 269 + .map_err(ServerError::ServerExited) 270 + } 251 271 }