refactor(snix/castore-http/cli): ask for root directory digest
Restrict the CLI to only root directories, passing the blake3 digest of the root directory. Usually we want to serve a directory, and we now have a `snix-castore ingest` sucommand, and copying the output from that command is much less effort than constructing a proto message. More advanced usecases can still use the get_root_node_contents library function and pass in other nodes. Change-Id: I66c2c0a15723b43b5b0cffc1c201391df57dd602 Reviewed-on: https://cl.snix.dev/c/snix/+/30321 Reviewed-by: Stefan Junker <mail@stefanjunker.de> Tested-by: besadii
This commit is contained in:
parent
fd5f316fb8
commit
d1990c9a93
5 changed files with 16 additions and 62 deletions
3
snix/Cargo.lock
generated
3
snix/Cargo.lock
generated
|
|
@ -4258,13 +4258,10 @@ dependencies = [
|
||||||
"axum-range",
|
"axum-range",
|
||||||
"axum-test",
|
"axum-test",
|
||||||
"blake3",
|
"blake3",
|
||||||
"bytes",
|
|
||||||
"clap",
|
"clap",
|
||||||
"data-encoding",
|
|
||||||
"mime",
|
"mime",
|
||||||
"mime_guess",
|
"mime_guess",
|
||||||
"path-clean",
|
"path-clean",
|
||||||
"prost",
|
|
||||||
"snix-castore",
|
"snix-castore",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-listener",
|
"tokio-listener",
|
||||||
|
|
|
||||||
|
|
@ -13966,19 +13966,11 @@ rec {
|
||||||
name = "axum-range";
|
name = "axum-range";
|
||||||
packageId = "axum-range";
|
packageId = "axum-range";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "bytes";
|
|
||||||
packageId = "bytes";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "clap";
|
name = "clap";
|
||||||
packageId = "clap";
|
packageId = "clap";
|
||||||
features = [ "derive" ];
|
features = [ "derive" ];
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "data-encoding";
|
|
||||||
packageId = "data-encoding";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "mime";
|
name = "mime";
|
||||||
packageId = "mime";
|
packageId = "mime";
|
||||||
|
|
@ -13991,10 +13983,6 @@ rec {
|
||||||
name = "path-clean";
|
name = "path-clean";
|
||||||
packageId = "path-clean";
|
packageId = "path-clean";
|
||||||
}
|
}
|
||||||
{
|
|
||||||
name = "prost";
|
|
||||||
packageId = "prost";
|
|
||||||
}
|
|
||||||
{
|
{
|
||||||
name = "snix-castore";
|
name = "snix-castore";
|
||||||
packageId = "snix-castore";
|
packageId = "snix-castore";
|
||||||
|
|
|
||||||
|
|
@ -8,13 +8,10 @@ anyhow.workspace = true
|
||||||
axum = { workspace = true, features = ["tracing"] }
|
axum = { workspace = true, features = ["tracing"] }
|
||||||
axum-extra.workspace = true
|
axum-extra.workspace = true
|
||||||
axum-range.workspace = true
|
axum-range.workspace = true
|
||||||
bytes.workspace = true
|
|
||||||
clap = { workspace = true, features = ["derive"] }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
data-encoding.workspace = true
|
|
||||||
mime_guess = "2.0.5"
|
mime_guess = "2.0.5"
|
||||||
mime = "0.3.17"
|
mime = "0.3.17"
|
||||||
path-clean.workspace = true
|
path-clean.workspace = true
|
||||||
prost.workspace = true
|
|
||||||
tokio = { workspace = true, features = [ "tracing"] }
|
tokio = { workspace = true, features = [ "tracing"] }
|
||||||
tokio-listener = { workspace = true, features = ["axum07", "clap", "multi-listener", "sd_listen"] }
|
tokio-listener = { workspace = true, features = ["axum07", "clap", "multi-listener", "sd_listen"] }
|
||||||
tracing.workspace = true
|
tracing.workspace = true
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use snix_castore::utils::ServiceUrlsGrpc;
|
use snix_castore::{utils::ServiceUrlsGrpc, B3Digest};
|
||||||
|
|
||||||
#[derive(Parser)]
|
#[derive(Parser)]
|
||||||
#[command(author, version, about)]
|
#[command(author, version, about)]
|
||||||
|
|
@ -10,13 +10,9 @@ pub struct CliArgs {
|
||||||
// The castore services addresses
|
// The castore services addresses
|
||||||
#[clap(flatten)]
|
#[clap(flatten)]
|
||||||
pub service_addrs: ServiceUrlsGrpc,
|
pub service_addrs: ServiceUrlsGrpc,
|
||||||
/// The castore root node to serve, URL-safe base64-encoded
|
/// The root directory digest to serve.
|
||||||
#[arg(
|
#[arg(short, long, help = "The root directory digest to serve")]
|
||||||
short,
|
pub root_directory: B3Digest,
|
||||||
long,
|
|
||||||
help = "The castore root node to serve, URL-safe base64-encoded"
|
|
||||||
)]
|
|
||||||
pub root_node: String,
|
|
||||||
/// The name of the file to serve if a client requests a directory e.g. index.html index.htm
|
/// The name of the file to serve if a client requests a directory e.g. index.html index.htm
|
||||||
#[arg(
|
#[arg(
|
||||||
short,
|
short,
|
||||||
|
|
|
||||||
|
|
@ -1,47 +1,23 @@
|
||||||
use snix_castore_http::cli::CliArgs;
|
|
||||||
|
|
||||||
use anyhow::{bail, Context};
|
|
||||||
use bytes::Bytes;
|
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use data_encoding::BASE64URL_NOPAD;
|
use snix_castore::Node;
|
||||||
use prost::Message;
|
use snix_castore_http::cli::CliArgs;
|
||||||
|
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> anyhow::Result<()> {
|
async fn main() -> anyhow::Result<()> {
|
||||||
tracing_subscriber::fmt().init();
|
tracing_subscriber::fmt().init();
|
||||||
|
|
||||||
let CliArgs {
|
let args: CliArgs = snix_castore_http::cli::CliArgs::parse();
|
||||||
listen_args,
|
|
||||||
service_addrs,
|
|
||||||
root_node,
|
|
||||||
index_names,
|
|
||||||
auto_index,
|
|
||||||
}: CliArgs = snix_castore_http::cli::CliArgs::parse();
|
|
||||||
|
|
||||||
// b64decode the root node passed *by the user*
|
|
||||||
let root_entry_proto = BASE64URL_NOPAD
|
|
||||||
.decode(root_node.as_bytes())
|
|
||||||
.context("unable to decode root node b64")?;
|
|
||||||
|
|
||||||
// check the proto size to be somewhat reasonable before parsing it.
|
|
||||||
if root_entry_proto.len() > 4096 {
|
|
||||||
bail!("rejected, too large root node");
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse the proto
|
|
||||||
let root_entry: snix_castore::proto::Entry = Message::decode(Bytes::from(root_entry_proto))
|
|
||||||
.context("unable to decode root node proto")?;
|
|
||||||
|
|
||||||
let root_node = root_entry
|
|
||||||
.try_into_anonymous_node()
|
|
||||||
.context("root node validation failed")?;
|
|
||||||
|
|
||||||
snix_castore_http::router::gen_router(
|
snix_castore_http::router::gen_router(
|
||||||
listen_args,
|
args.listen_args,
|
||||||
service_addrs,
|
args.service_addrs,
|
||||||
root_node,
|
Node::Directory {
|
||||||
&index_names,
|
digest: args.root_directory,
|
||||||
auto_index,
|
// size doesn't really matter here, we're not doing inode allocation.
|
||||||
|
size: 0,
|
||||||
|
},
|
||||||
|
&args.index_names,
|
||||||
|
args.auto_index,
|
||||||
)
|
)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue