parent
556035d278
commit
5b6d2c6cf7
11 changed files with 338 additions and 472 deletions
3
.dockerignore
Normal file
3
.dockerignore
Normal file
|
@ -0,0 +1,3 @@
|
|||
/target
|
||||
/run
|
||||
/.idea
|
29
.forgejo/workflows/build.yaml
Normal file
29
.forgejo/workflows/build.yaml
Normal file
|
@ -0,0 +1,29 @@
|
|||
name: "Build"
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- dev
|
||||
tags:
|
||||
- v**
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: "docker"
|
||||
|
||||
steps:
|
||||
- name: "Checkout"
|
||||
uses: "https://code.forgejo.org/actions/checkout@v4"
|
||||
|
||||
- name: "Login to the container registry"
|
||||
uses: "https://github.com/docker/login-action@v3"
|
||||
with:
|
||||
registry: git.moritzruth.de
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ github.token }}
|
||||
|
||||
- name: "Build and push"
|
||||
uses: "https://github.com/docker/build-push-action"
|
||||
with:
|
||||
file: "Containerfile"
|
||||
push: true
|
||||
tags: "git.moritzruth.de/moritzruth/sscdc:${{ github.ref_name }}"
|
565
Cargo.lock
generated
565
Cargo.lock
generated
|
@ -178,6 +178,16 @@ version = "0.5.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||
|
||||
[[package]]
|
||||
name = "async-attributes"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a3203e79f4dd9bdda415ed03cf14dae5a2bf775c683a00f94e9cd1faf0f596e5"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 1.0.109",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-channel"
|
||||
version = "1.9.0"
|
||||
|
@ -237,7 +247,6 @@ dependencies = [
|
|||
"blocking",
|
||||
"futures-lite 2.6.0",
|
||||
"once_cell",
|
||||
"tokio 1.43.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -316,18 +325,6 @@ dependencies = [
|
|||
"pin-project-lite 0.2.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-native-tls"
|
||||
version = "0.3.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e9e7a929bd34c68a82d58a4de7f86fffdaf97fb2af850162a7bb19dd7269b33"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"native-tls",
|
||||
"thiserror 1.0.69",
|
||||
"url",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "async-process"
|
||||
version = "2.3.0"
|
||||
|
@ -349,20 +346,20 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "async-session"
|
||||
version = "2.0.1"
|
||||
version = "3.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "345022a2eed092cd105cc1b26fd61c341e100bd5fcbbd792df4baf31c2cc631f"
|
||||
checksum = "07da4ce523b4e2ebaaf330746761df23a465b951a83d84bbce4233dabedae630"
|
||||
dependencies = [
|
||||
"anyhow",
|
||||
"async-std",
|
||||
"async-lock 2.8.0",
|
||||
"async-trait",
|
||||
"base64 0.12.3",
|
||||
"base64 0.13.1",
|
||||
"bincode",
|
||||
"blake3",
|
||||
"chrono",
|
||||
"hmac 0.8.1",
|
||||
"kv-log-macro",
|
||||
"rand 0.7.3",
|
||||
"hmac 0.11.0",
|
||||
"log",
|
||||
"rand 0.8.5",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"sha2",
|
||||
|
@ -406,6 +403,7 @@ version = "1.13.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c634475f29802fde2b8f0b505b1bd00dfe4df7d4a000f0b36f7671197d5c3615"
|
||||
dependencies = [
|
||||
"async-attributes",
|
||||
"async-channel 1.9.0",
|
||||
"async-global-executor",
|
||||
"async-io 2.4.0",
|
||||
|
@ -486,12 +484,6 @@ version = "0.2.11"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cbbc9d0964165b47557570cce6c952866c2678457aca742aafc9fb771d30270"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.12.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.13.1"
|
||||
|
@ -580,12 +572,6 @@ version = "1.5.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "0.5.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
|
||||
|
||||
[[package]]
|
||||
name = "bytes"
|
||||
version = "1.10.0"
|
||||
|
@ -619,6 +605,12 @@ version = "1.0.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "cfg_aliases"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724"
|
||||
|
||||
[[package]]
|
||||
name = "chrono"
|
||||
version = "0.4.40"
|
||||
|
@ -627,10 +619,8 @@ checksum = "1a7964611d71df112cb1730f2ee67324fcf4d0fc6606acbbe9bfe06df124637c"
|
|||
dependencies = [
|
||||
"android-tzdata",
|
||||
"iana-time-zone",
|
||||
"js-sys",
|
||||
"num-traits",
|
||||
"serde",
|
||||
"wasm-bindgen",
|
||||
"windows-link",
|
||||
]
|
||||
|
||||
|
@ -725,16 +715,6 @@ dependencies = [
|
|||
"version_check",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation"
|
||||
version = "0.9.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "core-foundation-sys"
|
||||
version = "0.8.7"
|
||||
|
@ -800,6 +780,16 @@ dependencies = [
|
|||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crypto-mac"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e"
|
||||
dependencies = [
|
||||
"generic-array",
|
||||
"subtle",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ctr"
|
||||
version = "0.6.0"
|
||||
|
@ -868,7 +858,7 @@ dependencies = [
|
|||
"crossbeam-queue",
|
||||
"num_cpus",
|
||||
"serde",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -908,15 +898,6 @@ dependencies = [
|
|||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "encoding_rs"
|
||||
version = "0.8.35"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "75030f3c4f45dafd7586dd6780965a8c7e8e285a5ecb86713e63a79c5b2766f3"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_filter"
|
||||
version = "0.1.3"
|
||||
|
@ -1063,21 +1044,6 @@ version = "1.0.7"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
|
||||
dependencies = [
|
||||
"foreign-types-shared",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "foreign-types-shared"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
|
||||
|
||||
[[package]]
|
||||
name = "form_urlencoded"
|
||||
version = "1.2.1"
|
||||
|
@ -1232,20 +1198,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"js-sys",
|
||||
"libc",
|
||||
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "getrandom"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"libc",
|
||||
"wasi 0.13.3+wasi-0.2.2",
|
||||
"windows-targets 0.52.6",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1276,25 +1232,6 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h2"
|
||||
version = "0.4.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5017294ff4bb30944501348f6f8e42e6ad28f42c8bbef7a74029aff064a4e3c2"
|
||||
dependencies = [
|
||||
"atomic-waker",
|
||||
"bytes 1.10.0",
|
||||
"fnv",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"http",
|
||||
"indexmap",
|
||||
"slab",
|
||||
"tokio 1.43.0",
|
||||
"tokio-util",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hashbrown"
|
||||
version = "0.14.5"
|
||||
|
@ -1329,16 +1266,6 @@ dependencies = [
|
|||
"hmac 0.10.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "126888268dcc288495a26bf004b38c5fdbb31682f992c84ceb046a1f0fe38840"
|
||||
dependencies = [
|
||||
"crypto-mac 0.8.0",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.10.1"
|
||||
|
@ -1349,13 +1276,23 @@ dependencies = [
|
|||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hmac"
|
||||
version = "0.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b"
|
||||
dependencies = [
|
||||
"crypto-mac 0.11.0",
|
||||
"digest",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "http"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"fnv",
|
||||
"itoa",
|
||||
]
|
||||
|
@ -1366,7 +1303,7 @@ version = "1.0.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"http",
|
||||
]
|
||||
|
||||
|
@ -1376,7 +1313,7 @@ version = "0.1.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"futures-util",
|
||||
"http",
|
||||
"http-body",
|
||||
|
@ -1390,7 +1327,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "1947510dc91e2bf586ea5ffb412caad7673264e14bb39fb9078da114a94ce1a5"
|
||||
dependencies = [
|
||||
"async-h1",
|
||||
"async-native-tls",
|
||||
"async-std",
|
||||
"async-trait",
|
||||
"cfg-if 1.0.0",
|
||||
|
@ -1399,7 +1335,6 @@ dependencies = [
|
|||
"futures",
|
||||
"http-types",
|
||||
"log",
|
||||
"tokio 0.2.25",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1442,17 +1377,16 @@ version = "1.6.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cc2b571658e38e0c01b1fdca3bbbe93c00d3d71693ff2770043f8c29bc7d6f80"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"httparse",
|
||||
"itoa",
|
||||
"pin-project-lite 0.2.16",
|
||||
"smallvec",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
"want",
|
||||
]
|
||||
|
||||
|
@ -1468,25 +1402,10 @@ dependencies = [
|
|||
"hyper-util",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower-service",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "hyper-tls"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "70206fc6890eaca9fde8a0bf71caa2ddfc9fe045ac9e5c70df101a7dbde866e0"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-util",
|
||||
"native-tls",
|
||||
"tokio 1.43.0",
|
||||
"tokio-native-tls",
|
||||
"tower-service",
|
||||
"webpki-roots",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1495,7 +1414,7 @@ version = "0.1.10"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "df2dcfbe0677734ab2f3ffa7fa7bfd4706bfdc1ef393f2ee30184aed67e631b4"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-util",
|
||||
"http",
|
||||
|
@ -1503,7 +1422,7 @@ dependencies = [
|
|||
"hyper",
|
||||
"pin-project-lite 0.2.16",
|
||||
"socket2 0.5.8",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
"tracing",
|
||||
]
|
||||
|
@ -1865,23 +1784,6 @@ dependencies = [
|
|||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "native-tls"
|
||||
version = "0.2.14"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "87de3442987e9dbec73158d5c715e7ad9072fda936bb03d19d7fa10e00520f0e"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"openssl",
|
||||
"openssl-probe",
|
||||
"openssl-sys",
|
||||
"schannel",
|
||||
"security-framework",
|
||||
"security-framework-sys",
|
||||
"tempfile",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "5.1.3"
|
||||
|
@ -1933,50 +1835,6 @@ version = "0.3.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381"
|
||||
|
||||
[[package]]
|
||||
name = "openssl"
|
||||
version = "0.10.71"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5e14130c6a98cd258fdcb0fb6d744152343ff729cbfcb28c656a9d12b999fbcd"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"cfg-if 1.0.0",
|
||||
"foreign-types",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"openssl-macros",
|
||||
"openssl-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "openssl-probe"
|
||||
version = "0.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d05e27ee213611ffe7d6348b942e8f942b37114c00cc03cec254295a4a17852e"
|
||||
|
||||
[[package]]
|
||||
name = "openssl-sys"
|
||||
version = "0.9.106"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8bb61ea9811cc39e3c2069f40b8b8e2e70d8569b361f879786cc7ed48b777cdd"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
"pkg-config",
|
||||
"vcpkg",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "owo-colors"
|
||||
version = "3.5.0"
|
||||
|
@ -2057,12 +1915,6 @@ dependencies = [
|
|||
"futures-io",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.31"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
|
||||
|
||||
[[package]]
|
||||
name = "polling"
|
||||
version = "2.8.0"
|
||||
|
@ -2151,6 +2003,58 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"pin-project-lite 0.2.16",
|
||||
"quinn-proto",
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"socket2 0.5.8",
|
||||
"thiserror 2.0.11",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-proto"
|
||||
version = "0.11.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d"
|
||||
dependencies = [
|
||||
"bytes",
|
||||
"getrandom 0.2.15",
|
||||
"rand 0.8.5",
|
||||
"ring",
|
||||
"rustc-hash",
|
||||
"rustls",
|
||||
"rustls-pki-types",
|
||||
"slab",
|
||||
"thiserror 2.0.11",
|
||||
"tinyvec",
|
||||
"tracing",
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944"
|
||||
dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2 0.5.8",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
|
@ -2276,42 +2180,40 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "43e734407157c3c2034e0258f5e4473ddb361b1e85f95a66690d67264d7cd1da"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"bytes 1.10.0",
|
||||
"encoding_rs",
|
||||
"bytes",
|
||||
"futures-channel",
|
||||
"futures-core",
|
||||
"futures-util",
|
||||
"h2",
|
||||
"http",
|
||||
"http-body",
|
||||
"http-body-util",
|
||||
"hyper",
|
||||
"hyper-rustls",
|
||||
"hyper-tls",
|
||||
"hyper-util",
|
||||
"ipnet",
|
||||
"js-sys",
|
||||
"log",
|
||||
"mime",
|
||||
"native-tls",
|
||||
"once_cell",
|
||||
"percent-encoding",
|
||||
"pin-project-lite 0.2.16",
|
||||
"quinn",
|
||||
"rustls",
|
||||
"rustls-pemfile",
|
||||
"rustls-pki-types",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"sync_wrapper",
|
||||
"system-configuration",
|
||||
"tokio 1.43.0",
|
||||
"tokio-native-tls",
|
||||
"tokio-util",
|
||||
"tokio",
|
||||
"tokio-rustls",
|
||||
"tower",
|
||||
"tower-service",
|
||||
"url",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"wasm-streams",
|
||||
"web-sys",
|
||||
"webpki-roots",
|
||||
"windows-registry",
|
||||
]
|
||||
|
||||
|
@ -2330,10 +2232,14 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "route-recognizer"
|
||||
version = "0.2.0"
|
||||
name = "routefinder"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e"
|
||||
checksum = "a44ef95cc607e41a7021da5cfb0f357ee0805113af2e9e6c617857c260940db4"
|
||||
dependencies = [
|
||||
"smartcow",
|
||||
"smartstring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-demangle"
|
||||
|
@ -2341,6 +2247,12 @@ version = "0.1.24"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -2384,6 +2296,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki",
|
||||
"subtle",
|
||||
|
@ -2404,6 +2317,9 @@ name = "rustls-pki-types"
|
|||
version = "1.11.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c"
|
||||
dependencies = [
|
||||
"web-time",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
|
@ -2428,44 +2344,12 @@ version = "1.0.19"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6ea1a2d0a644769cc99faa24c3ad26b379b786fe7c36fd3c546254801650e6dd"
|
||||
|
||||
[[package]]
|
||||
name = "schannel"
|
||||
version = "0.1.27"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f29ebaa345f945cec9fbbc532eb307f0fdad8161f281b6369539c8d84876b3d"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation",
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
"security-framework-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.14.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "0.9.0"
|
||||
|
@ -2637,6 +2521,24 @@ version = "1.14.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7fcf8323ef1faaee30a44a340193b1ac6814fd9b7b4e88e9d4519a3e4abe1cfd"
|
||||
|
||||
[[package]]
|
||||
name = "smartcow"
|
||||
version = "0.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "05e3ed3ccf93c7425507e5e2261a3fc90d14267d491f360b9b679ae0a4ce693e"
|
||||
dependencies = [
|
||||
"smartstring",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "smartstring"
|
||||
version = "0.2.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e714dff2b33f2321fdcd475b71cec79781a692d846f37f415fb395a1d2bcd48e"
|
||||
dependencies = [
|
||||
"static_assertions",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.4.10"
|
||||
|
@ -2667,7 +2569,6 @@ dependencies = [
|
|||
"color-eyre",
|
||||
"env_logger",
|
||||
"figment",
|
||||
"futures",
|
||||
"http-client",
|
||||
"log",
|
||||
"once_cell",
|
||||
|
@ -2677,7 +2578,6 @@ dependencies = [
|
|||
"serde_json",
|
||||
"serde_regex",
|
||||
"tide",
|
||||
"tokio 1.43.0",
|
||||
"toml",
|
||||
"validator",
|
||||
"zip",
|
||||
|
@ -2885,41 +2785,6 @@ dependencies = [
|
|||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration"
|
||||
version = "0.6.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3c879d448e9d986b661742763247d3693ed13609438cf3d006f51f5368a5ba6b"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
"core-foundation",
|
||||
"system-configuration-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "system-configuration-sys"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e1d1b10ced5ca923a1fcb8d03e96b8d3268065d724548c0211415ff6ac6bac4"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tempfile"
|
||||
version = "3.17.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230"
|
||||
dependencies = [
|
||||
"cfg-if 1.0.0",
|
||||
"fastrand 2.3.0",
|
||||
"getrandom 0.3.1",
|
||||
"once_cell",
|
||||
"rustix 0.38.44",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.69"
|
||||
|
@ -2972,9 +2837,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "tide"
|
||||
version = "0.16.0"
|
||||
version = "0.17.0-beta.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c459573f0dd2cc734b539047f57489ea875af8ee950860ded20cf93a79a1dee0"
|
||||
checksum = "c5a885fbeb66af9d607a731ce167e3fdfe65e49a68f37f4bbd8618b5efc6ad51"
|
||||
dependencies = [
|
||||
"async-h1",
|
||||
"async-session",
|
||||
|
@ -2988,7 +2853,7 @@ dependencies = [
|
|||
"kv-log-macro",
|
||||
"log",
|
||||
"pin-project-lite 0.2.16",
|
||||
"route-recognizer",
|
||||
"routefinder",
|
||||
"serde",
|
||||
"serde_json",
|
||||
]
|
||||
|
@ -3042,16 +2907,20 @@ dependencies = [
|
|||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "0.2.25"
|
||||
name = "tinyvec"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6703a273949a90131b290be1fe7b039d0fc884aa1935860dfcbe056f28cd8092"
|
||||
checksum = "022db8904dfa342efe721985167e9fcd16c29b226db4397ed752a761cfce81e8"
|
||||
dependencies = [
|
||||
"bytes 0.5.6",
|
||||
"pin-project-lite 0.1.12",
|
||||
"slab",
|
||||
"tinyvec_macros",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tinyvec_macros"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.43.0"
|
||||
|
@ -3059,37 +2928,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes 1.10.0",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"pin-project-lite 0.2.16",
|
||||
"signal-hook-registry",
|
||||
"socket2 0.5.8",
|
||||
"tokio-macros",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.5.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.98",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-native-tls"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||
dependencies = [
|
||||
"native-tls",
|
||||
"tokio 1.43.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-rustls"
|
||||
version = "0.26.1"
|
||||
|
@ -3097,20 +2943,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
checksum = "5f6d0975eaace0cf0fcadee4e4aaa5da15b5c079146f2cffb67c113be122bf37"
|
||||
dependencies = [
|
||||
"rustls",
|
||||
"tokio 1.43.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-util"
|
||||
version = "0.7.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d7fcaa8d55a2bdd6b83ace262b016eca0d79ee02818c5c1bcdf0305114081078"
|
||||
dependencies = [
|
||||
"bytes 1.10.0",
|
||||
"futures-core",
|
||||
"futures-sink",
|
||||
"pin-project-lite 0.2.16",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -3157,7 +2990,7 @@ dependencies = [
|
|||
"futures-util",
|
||||
"pin-project-lite 0.2.16",
|
||||
"sync_wrapper",
|
||||
"tokio 1.43.0",
|
||||
"tokio",
|
||||
"tower-layer",
|
||||
"tower-service",
|
||||
]
|
||||
|
@ -3296,9 +3129,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
|||
|
||||
[[package]]
|
||||
name = "validator"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d0b4a29d8709210980a09379f27ee31549b73292c87ab9899beee1c0d3be6303"
|
||||
checksum = "43fb22e1a008ece370ce08a3e9e4447a910e92621bb49b85d6e48a45397e7cfa"
|
||||
dependencies = [
|
||||
"idna",
|
||||
"once_cell",
|
||||
|
@ -3312,9 +3145,9 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "validator_derive"
|
||||
version = "0.19.0"
|
||||
version = "0.20.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bac855a2ce6f843beb229757e6e570a42e837bcb15e5f449dd48d5747d41bf77"
|
||||
checksum = "b7df16e474ef958526d1205f6dda359fdfab79d9aa6d54bafcb92dcd07673dca"
|
||||
dependencies = [
|
||||
"darling",
|
||||
"once_cell",
|
||||
|
@ -3366,12 +3199,6 @@ dependencies = [
|
|||
"sval_serde",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vcpkg"
|
||||
version = "0.2.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
|
||||
|
||||
[[package]]
|
||||
name = "version_check"
|
||||
version = "0.9.5"
|
||||
|
@ -3405,15 +3232,6 @@ version = "0.11.0+wasi-snapshot-preview1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||
|
||||
[[package]]
|
||||
name = "wasi"
|
||||
version = "0.13.3+wasi-0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
|
||||
dependencies = [
|
||||
"wit-bindgen-rt",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-bindgen"
|
||||
version = "0.2.100"
|
||||
|
@ -3487,19 +3305,6 @@ dependencies = [
|
|||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wasm-streams"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "15053d8d85c7eccdbefef60f06769760a563c7f0a9d6902a13d35c7800b0ad65"
|
||||
dependencies = [
|
||||
"futures-util",
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
"wasm-bindgen-futures",
|
||||
"web-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-sys"
|
||||
version = "0.3.77"
|
||||
|
@ -3510,6 +3315,25 @@ dependencies = [
|
|||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "web-time"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5a6580f308b1fad9207618087a65c04e7a10bc77e02c8e84e9b00dd4b12fa0bb"
|
||||
dependencies = [
|
||||
"js-sys",
|
||||
"wasm-bindgen",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "webpki-roots"
|
||||
version = "0.26.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9"
|
||||
dependencies = [
|
||||
"rustls-pki-types",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "winapi"
|
||||
version = "0.3.9"
|
||||
|
@ -3734,15 +3558,6 @@ dependencies = [
|
|||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "wit-bindgen-rt"
|
||||
version = "0.33.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
|
||||
dependencies = [
|
||||
"bitflags 2.8.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "write16"
|
||||
version = "1.0.0"
|
||||
|
|
34
Cargo.toml
34
Cargo.toml
|
@ -4,23 +4,21 @@ version = "0.1.0"
|
|||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
reqwest = { version = "0.12.12", features = ["json", "stream"] }
|
||||
toml = "0.8.19"
|
||||
serde = "1.0.217"
|
||||
validator = { version = "0.19.0", features = ["derive"] }
|
||||
figment = { version = "0.10.19", features = ["toml"] }
|
||||
color-eyre = "0.6.3"
|
||||
serde_regex = "1.1.0"
|
||||
regex = "1.11.1"
|
||||
tokio = { version = "1.43.0", default-features = false, features = ["macros", "process", "fs", "rt"] }
|
||||
log = "0.4.26"
|
||||
env_logger = "0.11.6"
|
||||
serde_json = "1.0.139"
|
||||
camino = "1.1.9"
|
||||
tide = { version = "0.16.0"}
|
||||
zip = { version = "2.2.3", default-features = false, features = ["deflate"] }
|
||||
futures = "0.3.31"
|
||||
async-std = { version = "1.13.0", features = ["tokio1"] }
|
||||
async-h1 = "2.3.4"
|
||||
http-client = { version = "6.5.3", features = ["async-h1", "tokio"] }
|
||||
async-std = { version = "1.13.0", features = ["attributes"] }
|
||||
camino = "1.1.9"
|
||||
color-eyre = "0.6.3"
|
||||
env_logger = "0.11.6"
|
||||
figment = { version = "0.10.19", features = ["toml"] }
|
||||
http-client = { version = "6.5.3", default-features = false, features = ["async-h1", "async-std", "h1_client"] }
|
||||
log = "0.4.26"
|
||||
once_cell = "1.20.3"
|
||||
regex = "1.11.1"
|
||||
reqwest = { version = "0.12.12", default-features = false, features = ["blocking", "rustls-tls"] }
|
||||
serde = "1.0.217"
|
||||
serde_json = "1.0.139"
|
||||
serde_regex = "1.1.0"
|
||||
tide = "0.17.0-beta.1"
|
||||
toml = "0.8.19"
|
||||
validator = { version = "0.20.0", features = ["derive"] }
|
||||
zip = { version = "2.2.3", default-features = false, features = ["deflate"] }
|
18
Containerfile
Normal file
18
Containerfile
Normal file
|
@ -0,0 +1,18 @@
|
|||
FROM docker.io/rustlang/rust:nightly-alpine AS app-builder
|
||||
WORKDIR /app
|
||||
COPY . /app
|
||||
RUN apk add musl-dev
|
||||
RUN CADDY_PATH=/caddy cargo build --release
|
||||
|
||||
FROM docker.io/caddy:builder-alpine AS caddy-builder
|
||||
RUN xcaddy build
|
||||
|
||||
FROM gcr.io/distroless/static-debian12
|
||||
COPY --from=app-builder /app/target/release/sscdc /
|
||||
COPY --from=caddy-builder /usr/bin/caddy /caddy
|
||||
|
||||
VOLUME "/config.toml"
|
||||
VOLUME "/sites"
|
||||
EXPOSE 80
|
||||
|
||||
CMD ["./sscdc"]
|
|
@ -1,2 +1,3 @@
|
|||
[toolchain]
|
||||
channel = "nightly"
|
||||
targets = ["x86_64-unknown-linux-musl"]
|
16
src/api.rs
16
src/api.rs
|
@ -2,14 +2,11 @@ use crate::config::Config;
|
|||
use crate::sites::SitesWorker;
|
||||
use camino::Utf8Path;
|
||||
use color_eyre::eyre::{WrapErr, eyre};
|
||||
use log::error;
|
||||
use serde::Deserialize;
|
||||
use std::str::pattern::Pattern;
|
||||
use std::sync::Arc;
|
||||
use tide::http::headers::HeaderName;
|
||||
use async_std::{fs, task};
|
||||
use async_std::task::JoinHandle;
|
||||
use tide::{Request, StatusCode};
|
||||
use tokio::fs;
|
||||
use tokio::task::JoinHandle;
|
||||
|
||||
#[derive(Clone)]
|
||||
struct State {
|
||||
|
@ -35,9 +32,9 @@ pub async fn start_api_server(
|
|||
server.at("/version").get(|_| async { Ok(env!("CARGO_PKG_VERSION")) });
|
||||
|
||||
let path = api_socket_path.to_path_buf().into_std_path_buf();
|
||||
fs::remove_file(&path).await?;
|
||||
let _ = fs::remove_file(&path).await;
|
||||
|
||||
Ok(tokio::spawn(async {
|
||||
Ok(task::spawn(async {
|
||||
server.listen(path).await.wrap_err("IO error in API server")?;
|
||||
Err(eyre!("The API unexpectedly stopped without error."))
|
||||
}))
|
||||
|
@ -68,6 +65,9 @@ async fn handle_notify(mut request: Request<State>) -> tide::Result {
|
|||
|
||||
Ok(StatusCode::NoContent.into())
|
||||
} else {
|
||||
Err(tide::Error::from_str(StatusCode::Unauthorized, "The provided secret is not valid for this domain."))
|
||||
Err(tide::Error::from_str(
|
||||
StatusCode::Unauthorized,
|
||||
"The provided secret is not valid for this domain.",
|
||||
))
|
||||
}
|
||||
}
|
||||
|
|
15
src/caddy.rs
15
src/caddy.rs
|
@ -8,9 +8,9 @@ use log::debug;
|
|||
use serde_json::json;
|
||||
use std::process::Stdio;
|
||||
use std::str::FromStr;
|
||||
use tokio::io::AsyncWriteExt;
|
||||
use tokio::process::Command;
|
||||
use tokio::time;
|
||||
use std::time::Duration;
|
||||
use async_std::io::WriteExt;
|
||||
use async_std::process::Command;
|
||||
|
||||
pub struct CaddyController {
|
||||
api_socket_path: Utf8PathBuf,
|
||||
|
@ -156,8 +156,11 @@ pub async fn start_caddy(api_socket_path: &Utf8Path, sockets_directory_path: &Ut
|
|||
// Stop not properly cleaned up proxy.
|
||||
let _ = request_uds(&caddy_admin_socket_path, Request::new(Method::Post, "http://localhost/stop")).await;
|
||||
|
||||
let caddy_path = option_env!("CADDY_PATH").unwrap_or("caddy");
|
||||
debug!("Caddy path: {}", caddy_path);
|
||||
|
||||
// Spawn a new proxy.
|
||||
let process = Command::new("caddy").args(&["run", "--config", "-"]).stdin(Stdio::piped()).spawn()?;
|
||||
let process = Command::new(caddy_path).args(&["run", "--config", "-"]).stdin(Stdio::piped()).spawn()?;
|
||||
|
||||
let initial_configuration_object = get_initial_caddy_configuration_object(&caddy_admin_socket_path, api_socket_path);
|
||||
let initial_configuration_string = initial_configuration_object.to_string();
|
||||
|
@ -165,11 +168,11 @@ pub async fn start_caddy(api_socket_path: &Utf8Path, sockets_directory_path: &Ut
|
|||
|
||||
process
|
||||
.stdin
|
||||
.ok_or_eyre("The caddy process stdin is not open.")?
|
||||
.ok_or_eyre("The Caddy process STDIN is not open.")?
|
||||
.write_all(initial_configuration_string.as_ref())
|
||||
.await?;
|
||||
|
||||
time::sleep(time::Duration::from_secs(1)).await;
|
||||
async_std::task::sleep(Duration::from_secs(1)).await;
|
||||
|
||||
Ok(CaddyController {
|
||||
api_socket_path: api_socket_path.to_path_buf(),
|
||||
|
|
|
@ -3,6 +3,7 @@ use figment::providers::{Format, Toml};
|
|||
use figment::Figment;
|
||||
use serde::Deserialize;
|
||||
use std::collections::HashMap;
|
||||
use async_std::task;
|
||||
use color_eyre::eyre::WrapErr;
|
||||
use once_cell::sync::Lazy;
|
||||
use regex::Regex;
|
||||
|
@ -10,7 +11,6 @@ use validator::Validate;
|
|||
|
||||
#[derive(Deserialize, Debug, Validate)]
|
||||
pub struct Config {
|
||||
pub port: u16,
|
||||
pub sites_directory: String,
|
||||
pub sockets_directory: String,
|
||||
#[validate(nested)]
|
||||
|
@ -27,11 +27,11 @@ pub struct ConfigScope {
|
|||
pub secret: String
|
||||
}
|
||||
|
||||
pub fn load_config() -> Result<Config> {
|
||||
let config: Config = Figment::new()
|
||||
pub async fn load_config() -> Result<Config> {
|
||||
let config: Config = task::spawn_blocking(|| Figment::new()
|
||||
.merge(Toml::file("./config.toml"))
|
||||
.extract()
|
||||
.wrap_err("Failed to load the configuration.")?;
|
||||
.wrap_err("Failed to load the configuration.")).await?;
|
||||
|
||||
config.validate().wrap_err("Failed to validate the configuration.")?;
|
||||
Ok(config)
|
||||
|
|
10
src/main.rs
10
src/main.rs
|
@ -10,24 +10,24 @@ use camino::Utf8Path;
|
|||
use color_eyre::Result;
|
||||
use color_eyre::eyre::WrapErr;
|
||||
use log::LevelFilter;
|
||||
use std::fs;
|
||||
use std::sync::Arc;
|
||||
use async_std::fs;
|
||||
|
||||
mod api;
|
||||
mod caddy;
|
||||
mod config;
|
||||
mod sites;
|
||||
|
||||
#[tokio::main(flavor = "current_thread")]
|
||||
#[async_std::main]
|
||||
async fn main() -> Result<()> {
|
||||
color_eyre::install()?;
|
||||
env_logger::Builder::new().filter_module("sscdc", LevelFilter::Info).parse_default_env().init();
|
||||
|
||||
log::info!("Loading configuration…");
|
||||
let config = load_config()?;
|
||||
let config = load_config().await?;
|
||||
|
||||
let sockets_directory_path = Utf8Path::new(&config.sockets_directory);
|
||||
fs::create_dir_all(&sockets_directory_path).wrap_err("Failed to access or create the sockets directory.")?;
|
||||
fs::create_dir_all(sockets_directory_path.as_std_path()).await.wrap_err("Failed to access or create the sockets directory.")?;
|
||||
let sockets_directory_path = sockets_directory_path.canonicalize_utf8().unwrap();
|
||||
let api_socket_path = sockets_directory_path.join("api.sock");
|
||||
|
||||
|
@ -41,5 +41,5 @@ async fn main() -> Result<()> {
|
|||
log::debug!("The internal API server is listening at {api_socket_path}");
|
||||
|
||||
log::info!("Startup complete.");
|
||||
sites_worker_join_handle.await??;
|
||||
sites_worker_join_handle.await?;
|
||||
}
|
||||
|
|
81
src/sites.rs
81
src/sites.rs
|
@ -1,19 +1,18 @@
|
|||
use crate::caddy::CaddyController;
|
||||
use async_std::io::{BufReader, BufWriter, WriteExt};
|
||||
use async_std::net::TcpStream;
|
||||
use async_std::stream::StreamExt;
|
||||
use async_std::sync::RwLock;
|
||||
use async_std::{fs, task};
|
||||
use camino::{Utf8Path, Utf8PathBuf};
|
||||
use color_eyre::Result;
|
||||
use color_eyre::eyre::{eyre, WrapErr};
|
||||
use futures::StreamExt;
|
||||
use color_eyre::eyre::{WrapErr, eyre};
|
||||
use log::{debug, info};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::{Arc, RwLockReadGuard, RwLockWriteGuard};
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tide::http::bail;
|
||||
use tokio::fs;
|
||||
use tokio::io::{AsyncWriteExt, BufWriter};
|
||||
use tokio::sync::mpsc::{UnboundedReceiver, UnboundedSender};
|
||||
use tokio::sync::{RwLock};
|
||||
use tokio::task::JoinHandle;
|
||||
use async_std::task::JoinHandle;
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
pub struct SiteState {
|
||||
|
@ -23,13 +22,13 @@ pub struct SiteState {
|
|||
|
||||
impl SiteState {
|
||||
async fn read_from_site_directory(site_directory_path: &Utf8Path) -> Result<Self> {
|
||||
let string = fs::read_to_string(site_directory_path.join("site.toml")).await?;
|
||||
let string = fs::read_to_string(site_directory_path.join("site.toml").into_std_path_buf()).await?;
|
||||
Ok(toml::from_str::<SiteState>(&string)?)
|
||||
}
|
||||
|
||||
async fn write_to_site_directory(&self, site_directory_path: &Utf8Path) -> Result<()> {
|
||||
fs::create_dir_all(site_directory_path).await?;
|
||||
let mut file = fs::File::create(site_directory_path.join("site.toml")).await?;
|
||||
fs::create_dir_all(site_directory_path.as_std_path()).await?;
|
||||
let mut file = fs::File::create(site_directory_path.join("site.toml").into_std_path_buf()).await?;
|
||||
file.write_all(toml::to_string(&self).unwrap().as_bytes()).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
@ -41,7 +40,7 @@ impl SiteState {
|
|||
return Some(current_version);
|
||||
}
|
||||
} else {
|
||||
return Some(current_version)
|
||||
return Some(current_version);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -66,7 +65,7 @@ type Sites = RwLock<HashMap<String, Arc<Site>>>;
|
|||
pub struct SitesWorker {
|
||||
sites: Arc<Sites>,
|
||||
sites_directory_path: Utf8PathBuf,
|
||||
download_tasks_sender: UnboundedSender<String>,
|
||||
download_tasks_sender: async_std::channel::Sender<String>,
|
||||
}
|
||||
|
||||
impl SitesWorker {
|
||||
|
@ -86,7 +85,7 @@ impl SitesWorker {
|
|||
let mut state = site.state.write().await;
|
||||
state.current_version = Some(SiteStateVersion { id, download_url });
|
||||
state.write_to_site_directory(&site.path).await?;
|
||||
self.download_tasks_sender.send(domain).unwrap();
|
||||
self.download_tasks_sender.send(domain).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -95,12 +94,13 @@ impl SitesWorker {
|
|||
pub async fn load_sites(sites_directory_path: &Utf8Path) -> Result<Sites> {
|
||||
let mut sites: HashMap<String, Arc<Site>> = HashMap::new();
|
||||
|
||||
if fs::try_exists(&sites_directory_path).await.unwrap_or(false) {
|
||||
let mut dir = fs::read_dir(&sites_directory_path).await?;
|
||||
if fs::metadata(sites_directory_path.as_std_path()).await.map(|m| m.is_dir()).unwrap_or(false) {
|
||||
let mut dir = fs::read_dir(sites_directory_path.as_std_path()).await?;
|
||||
loop {
|
||||
if let Some(entry) = dir.next_entry().await? {
|
||||
if let Some(entry) = dir.next().await {
|
||||
let entry = entry?;
|
||||
if entry.file_type().await?.is_dir() {
|
||||
let path = Utf8PathBuf::from_path_buf(entry.path()).unwrap();
|
||||
let path = Utf8PathBuf::from_path_buf(entry.path().into()).unwrap();
|
||||
let domain = path.file_name().unwrap().to_string();
|
||||
let state = SiteState::read_from_site_directory(&path).await?;
|
||||
|
||||
|
@ -118,7 +118,7 @@ pub async fn load_sites(sites_directory_path: &Utf8Path) -> Result<Sites> {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
fs::create_dir_all(&sites_directory_path)
|
||||
fs::create_dir_all(sites_directory_path.as_std_path())
|
||||
.await
|
||||
.wrap_err("Failed to create the sites directory (and its parents)")?;
|
||||
}
|
||||
|
@ -151,19 +151,19 @@ async fn handle_download(reqwest_client: &mut reqwest::Client, sites: &Sites, ca
|
|||
|
||||
// Download
|
||||
let archive_file_path = site.path.join(format!("{}.zip", current_version.id));
|
||||
let mut archive_file = fs::OpenOptions::new()
|
||||
let mut archive_file_for_writing = fs::OpenOptions::new()
|
||||
.truncate(true)
|
||||
.create(true)
|
||||
.write(true)
|
||||
.read(true)
|
||||
.open(&archive_file_path).await?;
|
||||
.open(archive_file_path.as_std_path())
|
||||
.await?;
|
||||
|
||||
let mut file_writer = BufWriter::new(&mut archive_file);
|
||||
let mut file_writer = BufWriter::new(&mut archive_file_for_writing);
|
||||
|
||||
let mut response = reqwest_client.get(¤t_version.download_url).send().await?;
|
||||
let status = response.status();
|
||||
if !status.is_success() {
|
||||
return Err(eyre!("Download request failed with status code {status}"))
|
||||
return Err(eyre!("Download request failed with status code {status}"));
|
||||
}
|
||||
|
||||
while let Some(chunk) = response.chunk().await? {
|
||||
|
@ -173,24 +173,23 @@ async fn handle_download(reqwest_client: &mut reqwest::Client, sites: &Sites, ca
|
|||
file_writer.flush().await?;
|
||||
|
||||
let extraction_directory_path = site.path.join(¤t_version.id);
|
||||
let _ = fs::remove_dir_all(&extraction_directory_path).await;
|
||||
fs::create_dir_all(&extraction_directory_path).await?;
|
||||
let _ = fs::remove_dir_all(extraction_directory_path.as_std_path()).await;
|
||||
fs::create_dir_all(extraction_directory_path.as_std_path()).await?;
|
||||
|
||||
debug!("Finished download for {domain} ({}), now unpacking…", current_version.id);
|
||||
|
||||
// Unpack to temp dir
|
||||
tokio::task::spawn_blocking({
|
||||
let archive_file = archive_file.into_std().await;
|
||||
task::spawn_blocking({
|
||||
let extraction_directory_path = extraction_directory_path.clone();
|
||||
let archive_file_path = archive_file_path.clone().into_std_path_buf();
|
||||
|
||||
move || -> Result<()> {
|
||||
let mut archive = zip::ZipArchive::new(archive_file)?;
|
||||
let mut archive = zip::ZipArchive::new(std::io::BufReader::new(std::fs::File::open(archive_file_path)?))?;
|
||||
archive.extract(&extraction_directory_path)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
})
|
||||
.await??;
|
||||
.await?;
|
||||
|
||||
// Update and write state
|
||||
let current_version = current_version.clone();
|
||||
|
@ -202,9 +201,9 @@ async fn handle_download(reqwest_client: &mut reqwest::Client, sites: &Sites, ca
|
|||
caddy_controller.upsert_site_configuration(&domain, &extraction_directory_path).await?;
|
||||
|
||||
// Cleanup
|
||||
fs::remove_file(archive_file_path).await?;
|
||||
fs::remove_file(archive_file_path.as_std_path()).await?;
|
||||
if let Some(old_active_version) = old_active_version {
|
||||
fs::remove_dir_all(site.path.join(old_active_version.id)).await?;
|
||||
fs::remove_dir_all(site.path.join(old_active_version.id).into_std_path_buf()).await?;
|
||||
}
|
||||
|
||||
info!("Cleanup finished for {domain}");
|
||||
|
@ -212,20 +211,20 @@ async fn handle_download(reqwest_client: &mut reqwest::Client, sites: &Sites, ca
|
|||
Ok(())
|
||||
}
|
||||
|
||||
async fn sites_worker(mut download_tasks_receiver: UnboundedReceiver<String>, sites: Arc<Sites>, mut caddy_controller: CaddyController) -> Result<!> {
|
||||
let mut client = reqwest::Client::builder()
|
||||
.read_timeout(Duration::from_secs(60))
|
||||
async fn sites_worker(mut download_tasks_receiver: async_std::channel::Receiver<String>, sites: Arc<Sites>, mut caddy_controller: CaddyController) -> Result<!> {
|
||||
let mut reqwest_client = reqwest::Client::builder()
|
||||
.read_timeout(Duration::from_mins(1))
|
||||
.timeout(Duration::from_hours(1))
|
||||
.build()?;
|
||||
|
||||
loop {
|
||||
let domain = download_tasks_receiver.recv().await.unwrap();
|
||||
handle_download(&mut client, &sites, &mut caddy_controller, domain).await?;
|
||||
handle_download(&mut reqwest_client, &sites, &mut caddy_controller, domain).await?;
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn start_sites_worker(sites_directory_path: Utf8PathBuf, mut caddy_controller: CaddyController) -> Result<(SitesWorker, JoinHandle<Result<!>>)> {
|
||||
let (download_tasks_sender, download_tasks_receiver) = tokio::sync::mpsc::unbounded_channel();
|
||||
let (download_tasks_sender, download_tasks_receiver) = async_std::channel::unbounded();
|
||||
|
||||
info!("Discovering managed sites…");
|
||||
let sites = Arc::new(load_sites(&sites_directory_path).await?);
|
||||
|
@ -249,14 +248,14 @@ pub async fn start_sites_worker(sites_directory_path: Utf8PathBuf, mut caddy_con
|
|||
|
||||
if is_outdated {
|
||||
outdated_count += 1;
|
||||
download_tasks_sender.send(site.domain.clone()).unwrap()
|
||||
download_tasks_sender.send(site.domain.clone()).await?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
info!("Discovered {total_count} site(s), {outdated_count} outdated.");
|
||||
|
||||
let join_handle = tokio::spawn(sites_worker(download_tasks_receiver, Arc::clone(&sites), caddy_controller));
|
||||
let join_handle = task::spawn(sites_worker(download_tasks_receiver, Arc::clone(&sites), caddy_controller));
|
||||
|
||||
Ok((
|
||||
SitesWorker {
|
||||
|
|
Loading…
Add table
Reference in a new issue