Support metadata-format = "json.zst" (#59)
* Support metadata-format = "json.zst"
* Use spawn_blocking for zstd decoding
Diff
CHANGELOG.md | 4 ++++
Cargo.lock | 77 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------
Cargo.toml | 1 +
config.toml | 29 ++++++++++++++++++++---------
src/config.rs | 43 +++++++++++++++++++++++++++++++++++++++++++
src/providers/gitlab.rs | 21 +++++++++++++--------
6 files changed, 131 insertions(+), 44 deletions(-)
@@ -1,3 +1,7 @@
# Unreleased
- Add optional `metadata-format` config. Options: `json` (default) & `json.zst`.
When the latter selected the server will fetch `metadata.json.zst` files.
# v0.1.3
- Add `ssl-cert` configuration value under `gitlab` to allow self-signed
@@ -281,9 +281,9 @@
[[package]]
name = "cc"
version = "1.0.83"
version = "1.0.84"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0"
checksum = "0f8e7c90afad890484a21653d08b6e209ae34770fb5ee298f9c699fcc1e5c856"
dependencies = [
"libc",
]
@@ -315,9 +315,9 @@
[[package]]
name = "clap"
version = "4.4.7"
version = "4.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
dependencies = [
"clap_builder",
"clap_derive",
@@ -325,9 +325,9 @@
[[package]]
name = "clap_builder"
version = "4.4.7"
version = "4.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
dependencies = [
"anstream",
"anstyle",
@@ -640,9 +640,9 @@
[[package]]
name = "getrandom"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be4136b2a15dd319360be1c07d9933517ccf0be8f16bf62a3bee4f0d618df427"
checksum = "fe9006bed769170c11f845cf00c7c1e9092aeb3f268e007c3e760ac68008070f"
dependencies = [
"cfg-if",
"libc",
@@ -693,6 +693,7 @@
"urlencoding",
"ustr",
"uuid",
"zstd",
]
[[package]]
@@ -756,9 +757,9 @@
[[package]]
name = "http"
version = "0.2.9"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bd6effc99afb63425aff9b05836f029929e345a6148a14b7ecd5ab67af944482"
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
dependencies = [
"bytes",
"fnv",
@@ -929,9 +930,9 @@
[[package]]
name = "linux-raw-sys"
version = "0.4.10"
version = "0.4.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da2479e8c062e40bf0066ffa0bc823de0a9368974af99c9f6df941d2c231e03f"
checksum = "969488b55f8ac402214f3f5fd243ebb7206cf82de60d3172994707a4bcc2b829"
[[package]]
name = "lock_api"
@@ -1369,9 +1370,9 @@
[[package]]
name = "rustls-pemfile"
version = "1.0.3"
version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d3987094b1d07b653b7dfdc3f70ce9a1da9c51ac18c1b06b662e4f9a0e9f4b2"
checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c"
dependencies = [
"base64",
]
@@ -1539,9 +1540,9 @@
[[package]]
name = "smallvec"
version = "1.11.1"
version = "1.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "942b4a808e05215192e39f4ab80813e599068285906cc91aa64f923db842bd5a"
checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970"
[[package]]
name = "socket2"
@@ -1765,9 +1766,9 @@
[[package]]
name = "tokio"
version = "1.33.0"
version = "1.34.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f38200e3ef7995e5ef13baec2f432a6da0aa9ac495b2c0e8f3b7eec2c92d653"
checksum = "d0c014766411e834f7af5b8f4cf46257aab4036ca95e9d2c144a10f59ad6f5b9"
dependencies = [
"backtrace",
"bytes",
@@ -1784,9 +1785,9 @@
[[package]]
name = "tokio-macros"
version = "2.1.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
@@ -1877,9 +1878,9 @@
[[package]]
name = "tracing-log"
version = "0.1.4"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
@@ -1888,9 +1889,9 @@
[[package]]
name = "tracing-subscriber"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"nu-ansi-term",
"sharded-slab",
@@ -2244,4 +2245,32 @@
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "zstd"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bffb3309596d527cfcba7dfc6ed6052f1d39dfbd7c867aa2e865e4a449c10110"
dependencies = [
"zstd-safe",
]
[[package]]
name = "zstd-safe"
version = "7.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43747c7422e2924c11144d5229878b98180ef8b06cca4ab5af37afc8a8d8ea3e"
dependencies = [
"zstd-sys",
]
[[package]]
name = "zstd-sys"
version = "2.0.9+zstd.1.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9e16efa8a874a0481a574084d34cc26fdb3b99627480f785888deb6386506656"
dependencies = [
"cc",
"pkg-config",
]
@@ -41,6 +41,7 @@
urlencoding = "2.1"
ustr = "0.10"
uuid = { version = "1.1", features = ["v4"] }
zstd = "0.13"
[profile.release]
lto = "thin"
@@ -1,18 +1,25 @@
listen-address = "[::]:2222"
state-directory = "/var/lib/gitlab-cargo-shim"
[gitlab]
uri = "http://127.0.0.1:3000"
admin-token = "personal-access-token"
@@ -1,5 +1,6 @@
#![allow(clippy::module_name_repetitions)]
use crate::providers::gitlab::handle_error;
use clap::Parser;
use serde::{de::DeserializeOwned, Deserialize};
use std::{io, net::SocketAddr, path::PathBuf, str::FromStr};
@@ -39,12 +40,54 @@
pub token_expiry: Duration,
#[serde(default)]
pub ssl_cert: Option<String>,
#[serde(default)]
pub metadata_format: MetadataFormat,
}
impl GitlabConfig {
#[must_use]
const fn default_token_expiry() -> Duration {
Duration::days(30)
}
}
#[derive(Default, Debug, Clone, Copy, PartialEq, Eq, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum MetadataFormat {
#[default]
Json,
#[serde(rename = "json.zst")]
JsonZst,
}
impl MetadataFormat {
#[must_use]
pub fn filename(self) -> &'static str {
match self {
Self::Json => "metadata.json",
Self::JsonZst => "metadata.json.zst",
}
}
pub async fn decode(self, res: reqwest::Response) -> anyhow::Result<cargo_metadata::Metadata> {
match self {
Self::Json => Ok(handle_error(res).await?.json().await?),
Self::JsonZst => {
let body = handle_error(res).await?.bytes().await?;
tokio::task::spawn_blocking(move || {
Ok(serde_json::from_reader(zstd::Decoder::new(body.as_ref())?)?)
})
.await?
}
}
}
}
@@ -1,7 +1,7 @@
#![allow(clippy::module_name_repetitions)]
use crate::{
config::GitlabConfig,
config::{GitlabConfig, MetadataFormat},
providers::{Release, User},
};
use async_trait::async_trait;
@@ -19,6 +19,7 @@
base_url: Url,
token_expiry: Duration,
ssl_cert: Option<Certificate>,
metadata_format: MetadataFormat,
}
impl Gitlab {
@@ -46,6 +47,7 @@
base_url: config.uri.join("api/v4/")?,
token_expiry: config.token_expiry,
ssl_cert,
metadata_format: config.metadata_format,
})
}
@@ -288,16 +290,17 @@
version: &str,
do_as: &User,
) -> anyhow::Result<cargo_metadata::Metadata> {
let uri = self.base_url.join(&path.metadata_uri(version))?;
let fmt = self.metadata_format;
let url = self
.base_url
.join(&path.file_uri(fmt.filename(), version))?;
let client = match &do_as.token {
None => self.client.clone(),
Some(token) => self.build_client_with_token("PRIVATE-TOKEN", token)?,
};
Ok(handle_error(client.get(uri).send().await?)
.await?
.json()
.await?)
fmt.decode(client.get(url).send().await?).await
}
fn cargo_dl_uri(&self, project: &str, token: &str) -> anyhow::Result<String> {
@@ -309,7 +312,7 @@
}
}
async fn handle_error(resp: reqwest::Response) -> Result<reqwest::Response, anyhow::Error> {
pub async fn handle_error(resp: reqwest::Response) -> Result<reqwest::Response, anyhow::Error> {
if resp.status().is_success() {
Ok(resp)
} else {
@@ -336,9 +339,9 @@
impl GitlabCratePath {
#[must_use]
pub fn metadata_uri(&self, version: &str) -> String {
pub fn file_uri(&self, file: &str, version: &str) -> String {
format!(
"projects/{}/packages/generic/{}/{version}/metadata.json",
"projects/{}/packages/generic/{}/{version}/{file}",
self.project, self.package_name
)
}